A terminal window on a Linux laptop.
Fatmawati Achmad Zaenuri/Shutterstock

We use the Linux ls command every day without thinking about it. That’s a pity. Pay it some attention, and you’ll find many useful options—including some you should add to your command-line arsenal.

ls Lists Files and Directories

The ls command is probably the first command most Linux users encounter. Those of us who hang around the command line use it day in and day out without even thinking about it. That might explain why there is more to this command than most users realize. We list files with it to see what’s in a directory. We list files in long format when we want to look at the permissions on a file. Beyond that, it gets little consideration.

The ls command is one of those commands with a wealth of options. Perhaps this is part of the problem. There are so many options, how do you sift through them to find the useful ones? And having found them, how do you remember them?

Useful permutations of the ls command with their strings of options and parameters are the perfect candidates for aliases. In fact, in most distributions, what you think of as the “naked” ls command is actually an alias. Amongst other things, the type command can be used to show the underlying definition of aliases. Let’s look at the definition of ls:

type ls

type ls in a terminal window

The --color=auto parameters are included automatically every time you use the ls command. This is what provides the different colors for the different file types in the listings.

RELATED: How to Create Aliases and Shell Functions on Linux

Simple ls Listings

Everyone who’s spent some time using the Linux terminal knows that, by default, ls lists the files and directories in the current directory.

ls

ls in a terminal window

If you want to have your listing produced ina single column, use the -1 (one file per line) option:

ls -1

ls -1 in a terminal window

We’ll discuss that weird-looking filename at the top of the listing in a minute.

Using ls on Different Directories

To have ls list the files in a directory other than the current directory, pass the path to the directory to ls on the command line. You can also pass more than one directory to ls, and have them listed one after the other. Here, we’re asking ls to list the files in two directories, one called “Help” and the other called “gc_help.”

ls Help gc_help

ls Help gc_help in a terminal window

When ls has listed the contents of the first directory it lists the contents of the second. It prints the name of each directory as it processes them:

Name of the directory being displayed by ls before the contents are listed.

Using File Patterns

To selectively list a set of files, use pattern matching. The question mark “?” will represent any single character and the asterisk “*” will represent any string of characters. To list any files or directories that have names starting with “ip_” use this format:

ls ip_*

ls ip_* in a terminal window

To list files that have “.c” extensions, use this format:

ls *.c

ls *.c in a terminal window

You can also use ls with grep , and use grep‘s pattern matching capabilities. Let’s look for any files that have the string “_pin_” in their name:

ls | grep _pin_

ls | grep _pin_ in a terminal window

This is almost the same as using ls on its own, with two wildcards:

ls | grep _pin_
ls *_pin_*

ls | grep _pin_ in a terminal window

Why almost the same? Note the different layouts. grep forces the output to a single filename per line format.

Non-Printing Characters

It is possible to find yourself with a filename that has a non-printing or control-character in its filename. Typically this can happen when you expand an archive you’ve downloaded from the web or retrieved a git repository, and the original author made a mistake creating a file but didn’t spot it.

Our weird file is one of these:

Filename with control character in it in a terminal window

If we look at it in the file browser and press “F2” to rename it, the non-printing characters are represented by a strange symbol.

Filename with a control characater in it, in the renaming dialog window

You can use the -b (escape) option to allow you to see what the file name actually contains. This option causes ls to use the escape sequences of the C programming language to represent the control-characters.

ls -b a*

ls -b a* in a terminal window

The mysterious character is revealed to be a newline character, represented in C as “\n.”

Ignoring Files

To have certain files omitted from a listing, use the --hide option. Suppose you don’t want to see the backup “.bak” files in the listing. You could use this command:

ls
ls --hide=*.bak

ls --hide=*.bak in a terminal window

The “.bak” files are not included in the second listing.

The Long Format Listing

The -l (long listing) option causes ls to provide detailed information about each file.

ls -l

ls -l in a terminal window

There’s a lot of information here, so let’s step through it.

The first thing ls displays is the total size of all the files in the listing. Then each file or directory is displayed on a line by itself.

The first set of ten letters and dashes are the file type and the owner, group and other file permissions.

The very first character represents the file type. It will be one of:

  • :  A regular file.
  • b: A block special file.
  • c: A character special file.
  • d: A directory.
  • l: A symbolic link.
  • n: A network file.
  • p: A named pipe.
  • s: A socket.

The next nine characters are three groups of three characters displayed contiguously. Each group of three represent the read, write, and execute permissions, in that order. If the permission is granted, there will be an r, w, or x present. If the permission is not granted, a hyphen - is shown.

The first set of three characters are the permissions for the file owner. The second set of three permissions are for group members, and the last set of three permissions is for others.

Sometimes the execution permission for the owner is represented by an s. This is the setuid bit. If it is present, it means that the file is executed with the privileges of the file owner, not the user executing the file.

The execution permission for the group can also be an s.  This is the setgid bit. When this is applied to a file, it means the file will be executed with the privileges of the ower’s group. When used with a directory, any files created inside it will take their group permissions from the directory they’re being created in, not from the user who is creating the file.

The execution permission for the others can sometimes be represented by a t. This is the sticky bit. It is usually applied to directories. If this is set, regardless of the write and executable privileges that are set on the files in the directory, only the file owner, the directory owner, or the root user can rename or delete files in the directory.

A common use for the sticky bit is on folders such as “/tmp”. This is writable by all users on the computer. The sticky bit on the directory ensures that users—and processes launched by the users—can only rename or delete their own temporary files.

We can see the sticky bit on the “/tmp” directory. Note the use of the -d (directory) option. This causes ls to report on the details of the directory. Without this option, ls will report on the files inside the directory.

ls -l -d /tmp

ls -l -d /tmp in a terminal window

RELATED: How to Use the chmod Command on Linux

The number following the permissions is the number of hard links to the file or directory. For a file, this is usually one, but if other hard links are created, this number will increase. A directory typically has at least two hard links. One is a link to itself, and the other is its entry in its parent directory.

The name of the owner and group are displayed next. They are followed by the file size and the date of the last modification of the file. Finally, the filename is given.

Human Readable File Sizes

Having the file sizes in bytes is not always convenient. To see the file sizes in the most appropriate units (Kilobytes, Megabytes, etc.) use the -h (human-readable) option:

ls -l -h

ls -l -h in a terminal window

Showing Hidden Files

To see hidden files, use the -a (all) option:

ls -l -a

ls -l -a in a terminal window

The two entries “.” and “..” represent the current directory and the parent directory, respectively. A file called “.base_settings” is now visible for the first time.

Omitting . and .. from Listings

If you don’t want your listing cluttered up with the “.” and “..” entries, but you do want to see hidden files, use the -A (almost all) option:

ls -l -A

ls -l -A in a terminal window

The hidden file is still listed, but the “.” and “..” entries are suppressed.

Listing Directories Recursively

To have ls list the files in all subdirectories use the -R (recursive) option

ls -l -R

ls -l -R in a terminal window

ls works its way through the entire directory tree below the starting directory, and lists the files in each subdirectory.

output from ls recursively listing directories

Displaying the UID and GID

To have the user ID and group ID displayed instead of the user name and group name, use the -n (numeric uid and gid) option.

ls -n

ls -n in a terminal window

Sorting The Listings

You can sort the listing by extension, file size, or modification time. These options don’t have to be used with the long listing format, but it usually makes sense to do so. If you’re sorting by file size, it makes sense to see the file sizes in the listing. When you’re sorting by extension type, the long listing format isn’t so important.

To sort by extension, use the -X (sort by extension) option.

ls -X -1

ls -X -1 in a terminal window

The directories are listed first (no extensions at all) then the rest follow in alphabetical order, according to the extensions.

To sort by file size, use the -S (sort by file size) option.

ls -l -h -S

ls -l -h -S in a terminal window

The sort order is largest to smallest.

To sort the listing by modification time, use the -t (sort by modification time) option.

ls -l -t

ls -l -t in a terminal window

The listing is sorted by the modification time.

If the file modification time is within the current year, the information displayed is the month, day, and time. If the modification date was not in the current year, the information that is displayed is the month, day, and the year.

A quick way to get the newest and oldest files in a directory is to use ls with the head and tail commands.

To get the newest file or directory, use this command:

ls -t | head -1

To get the oldest file or directory, use this command:

ls -t | tail -1

ls -t | head -1 in a terminal window

To Reverse the Sort Order

To reverse any of the sort orders, use the -r (reverse) option.

ls -l -h -S -r

ls -l -h -S -r in a terminal window

The listing is now ordered from the smallest file to the largest file.

And there’s more

Check out the man page for lsthere are many more options. Some of them satisfy somewhat obscure use cases, but once in a while, you’ll be glad you know about them.

Do you need to see the file timestamps with the maximum precision that Linux can provide? Use the full-time option:

ls --full-time

Perhaps you want to see the inode number of the files? Use the inode option:

ls -i

Are you working on a monochrome display and want to remove all risk of confusing files for directories and links? Use the classify option, and ls will append one of these to each listing entry:

  • /: A directory.
  • @: A symlink.
  • |: A named pipe.
  • =: A socket.
  • *: An executable files
ls -F

Do some digging. You’ll find that ls is a rich vein, and you’ll keep turning up gems.

Dave McKay Dave McKay
Dave McKay first used computers when punched paper tape was in vogue, and he has been programming ever since. He is now a Data Protection Officer and has worked as a freelance programmer, manager of an international software development team, and an IT services project manager. Dave is a Linux evangelist and open source advocate.
Read Full Bio »