ls is most useful for its default task – listing alphabetically all the non–hidden files in a directory, in a human–readable form, with color coding for special files like directories, executables and symlinks. When exploring a directory, ls and globs can be enough to get a broad idea of where things are.

Unfortunately ls is useless for reliable scripting — see Why you shouldn’t parse the output of ls(1) and Why *not* parse `ls` (and what to do instead)? Anything we could possibly want to do in a script can be done more reliably with find or globs. With that in mind, here are some handy ls options and their scriptable counterparts:

List all files except . and ..

ls command: ls --almost-all Scripting: find — it lists hidden files by default

Print file metadata

  • ls command: ls -l

  • Scripting: find -printf PATTERN prints arbitrary metadata

Reverse order

  • ls command: ls --reverse

  • Scripting: find EXPRESSION -print0 | sort --reverse --zero-terminated

Order by most recent first

  • ls command: ls -t

  • Scripting: find PATH… -printf '%[email protected]\t%p\0' | sort --key=1 --reverse --zero-terminated | cut --fields=2 --zero-terminated


locate website

The mlocate package contains two handy tools: updatedb to create and update an index of all the files on your system and locate to search through the index. locate STRING lists all paths which contain the given string. Because mlocate keeps track of paths in a database it is much faster than find / -path STRING, but since it’s a separate database it’s not necessarily up–to–date. updatedb usually runs as part of a cron job installed as part of the package, for example in /etc/cron.daily/mlocate, but you can also run sudo updatedb to update it anytime.

updatedb may be configured to exclude some filesystems and paths by default. For example, on my system it excludes network file systems (which could take a long time to index) and the /tmp directory, among many others.

When using locate we have to be careful not to match too many things. For example, locate /foo will print any directory with a name starting with “foo” and any files inside such directories.

  • To limit this to directories with an exact name and all files within them we can use locate /foo/.

  • To limit it to only files called “foo” we can use locate --regex '/foo$'.

  • Printing only directories with a specific name is not supported, because locate doesn’t distinguish between directories and other files.


This page is a preview of The newline Guide to Bash Scripting

No discussions yet