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.
Top comments (0)