When you SSH into a Linux server, ls is often the fastest way to get your bearings. But a directory listing can hide files, show a directory’s contents when you meant to inspect the directory itself, or make a size look more meaningful than it is.

Here’s a practical way to use ls and understand what it’s telling you.

Start with the view you need

With no arguments, ls lists non-hidden entries in your current directory. Pass a path to inspect another location:

ls ls /var/log 

For a more useful inspection view, combine long format, hidden entries, and readable sizes:

ls -alh 

The options can be combined in either order. -l shows metadata, -a includes hidden entries, and -h displays sizes in units such as K or M when used with a size-reporting option like -l.

If you want hidden names without the special . and .. entries, use -A instead:

ls -A 

A quick reference for the options used most often:

Option What it does
-l Shows permissions, owner, group, size, and modification time
-a Includes hidden names, plus . and ..
-A Includes hidden names but omits . and ..
-h Uses readable size units with -l or -s
-1 Prints one entry per line
-t Sorts by modification time, newest first
-S Sorts by reported file size, largest first
-R Lists directory contents recursively

A directory path can mean two different things

When you pass a directory to ls, it normally lists what’s inside it:

ls project 

To show the directory entry itself, add -d:

ls -d project 

That distinction is especially handy with shell patterns. In a Bash-like shell, */ expands to directory names in the current location. Use -d to print those names rather than their contents:

ls -d */ 

This only matches directories in the current location; it does not search recursively.

For a quick tree-style dump, -R recursively lists a directory and its contents:

ls -R project 

Be careful with large directories: recursive output can become extensive. If you only need a quick inventory, a non-recursive listing is easier to scan.

Read long output without guessing

A long listing might look like this:

-rw-r--r-- 1 sam developers 1.2K Oct 10 09:30 notes.txt 

The first field contains the entry type and permissions. The remaining fields show the hard-link count, owner, group, reported size, modification time, and name. Common type characters include - for a regular file, d for a directory, and l for a symbolic link.

The size in ls -l is not a directory’s total contents. It reports metadata for the directory entry, not the total disk space used by everything inside. For usage totals, use du; du -sh and related directory-size checks are useful when you’re tracking down what’s using space. For a closer look at permissions and every long-listing column, see this breakdown of ls -al.

You can sort a listing by modification time or size:

ls -lt # newest modified entries first ls -ltr # oldest modified entries first ls -lS # largest reported file sizes first 

These sorts use modification time and reported file size, respectively. They don’t tell you when a file was created or how much space a directory tree uses.

Patterns, spaces, and useful output formats

Shell wildcards are expanded before ls runs. For example, this lists matching names in the current directory:

ls *.conf 

If a path includes spaces, quote it so the shell passes it as one argument:

ls "Project Files" 

For output that’s easier to read line by line, use -1:

ls -1 

You can also ask GNU ls to append indicators such as / for directories and * for executables:

ls -F 

Some options, including --color and version sorting with -v, are specific to GNU ls. If you’re on a different Unix-like system, check the local manual rather than assuming every option is available.

When a listing looks wrong

Hidden files are missing: Use ls -A. Names beginning with a dot are hidden from the default listing.

The output is empty: You may be in a different directory than expected, or the directory may contain only hidden entries. Check your location with pwd, then try ls -A.

A path isn’t found: Check spelling and capitalization. Linux filenames are case-sensitive, and a relative path is interpreted from your current directory. Quote paths that contain spaces.

You see “Permission denied”: Listing a directory’s contents requires permission to read it; accessing a path also requires search (execute) permission on its parent directories. Inspect the directory entry first with:

ls -ld /path/to/directory 

Don’t reach for sudo automatically. Confirm the path and account before escalating privileges.

If an option behaves unexpectedly, ls may be an alias or have different platform-specific behavior. Check with type ls, and consult man ls for the version installed on your system.

The quick mental model

Use ls to inspect names and metadata. Add -a or -A when hidden entries matter, -l when you need details, and -d when you want the directory itself rather than its contents. For total directory usage, switch to du—a listing is not a disk-usage report.

I originally published a more detailed version of this guide on the SSHFlow blog.

I'm also building SSHFlow — an SSH client where every server gets its own workspace for terminals, SFTP, code, and databases.