Skip to main content

Linux command: ls

03 June 2026

If you use Linux, you use ls. It is one of the first commands every new user learns, and one of the last commands an experienced administrator gives up. You type it on your laptop, on a web server over SSH, and inside a tiny rescue shell when something has gone wrong.

1. The basics

The job of ls is simple: it lists the contents of a directory. Before you copy, move, delete, or edit a file, you run ls to see what is actually there. In that sense ls is your eyes on the filesystem.

Two things make ls special. First, it is safe. The command only reads; it never changes a file. You can run it freely while exploring an unfamiliar server, and you cannot break anything. Second, it is informative. A handful of flags answers almost every everyday question: what is here, how big is it, how old is it, and who owns it?

The command you type a hundred times a day. Behind that tiny two-letter name sits decades of Unix history, a surprising number of options, and a direct window into how a filesystem really works.

This article starts with the simplest possible use and builds up step by step to advanced techniques. Along the way you will also learn how Linux stores files, what permissions mean, and what an inode is. By the end, a line of ls -l output will read like a sentence.

The right mental model: a directory is just a list of names that point at files. ls reads that list and shows it to you. Every flag is a different question about that list.

Back to top

2. Where the Name Comes From

The name ls is short for list, as in "list directory contents".

ls  =  LiSt

Why drop the vowels? Early Unix was typed on slow teletype terminals, where every keystroke was printed onto paper one character at a time. Short commands saved time and ink. This is also why so many core commands are two letters: cp (copy), mv (move), rm (remove), cd (change directory), and ls (list). Short names were simply the house style.

That habit has lasted for fifty years. Once a command name is in everybody's muscle memory, there is no good reason to make it longer. So ls stays ls.

Back to top

3. A Short History

The ls command is older than Linux itself. It first appeared in Multics, the operating-system project that Unix grew out of, and then shipped in Unix 1st Edition at Bell Labs in 1971. It has been present on every Unix-like system ever since: Linux, macOS, the BSDs, Solaris, and AIX.

EraMilestone
~1965 ls exists in Multics
1971 Ships in Unix 1st Edition
1980s BSD adds colour, columns, and the -G flag
Today The GNU coreutils ls runs on most Linux distributions

There are two main versions you will meet in practice. Most Linux systems run the GNU coreutils version of ls. macOS and the BSDs ship the BSD version. They are about 95% the same; the differences are mostly in colour flags and a few long options. This article uses the GNU version, which is what you will find on almost every Linux server.

A command over fifty years old, still used every day and essentially unchanged in spirit, is proof that good interface design lasts.

Back to top

4. Simple Use Cases

4.1 The Simplest Possible Use

Type ls with nothing after it. It lists the current directory. In the examples below, the line that starts with $ is what you type, and the lines under it are what the system prints back.

$ ls
Documents  Downloads  Music  Pictures  notes.txt  todo.md

Three things happen by default:

  • Entries are sorted alphabetically.
  • They are arranged in columns to fit the width of your terminal.
  • Hidden files are not shown (more on those in a moment).

4.2 Pointing ls at a Path

You can tell ls exactly what to look at, instead of the current directory:

$ ls /etc                 # a specific directory by absolute path
$ ls Documents            # a subfolder by relative path
$ ls notes.txt            # confirm a single file exists
$ ls Documents Downloads  # several things at once

This gives you a quick test. If ls shows the name, the file exists and you are allowed to read the directory. If it returns an error, you either have the wrong path or you do not have permission.

4.3 Seeing Hidden Files: -a

Files whose names begin with a dot (.) are "hidden" by convention. They are usually configuration files you do not need to see every day. The -a flag (short for all) reveals them:

$ ls -a
.   ..   .bashrc   .config   .ssh   Documents   notes.txt
EntryMeaning
. This directory
.. The parent directory
.bashrc A hidden configuration file

A leading dot is just a naming convention that ls honours; there is nothing magic about the file itself. If the two extra entries . and .. get in your way, use -A ("almost all"), which shows hidden files but hides . and ...

4.4 The Long Format: -l

This is the flag you will use most. The -l flag (short for long) shows one file per line, with full details:

$ ls -l
drwxr-xr-x  2 peter staff  4096 Jun  1 09:14 Documents
-rw-r--r--  1 peter staff  1234 May 28 17:02 notes.txt

Each column has a fixed meaning. Read them from left to right:

ColumnWhat it tells you
-rw-r--r-- File type and permissions (explained in section 6)
1 Number of hard links
peter Owner
staff Group
1234 Size in bytes
May 28 17:02 Last modification time
notes.txt The name

ls -l is the difference between "what is here?" and "tell me everything about what is here".

Back to top

5. Moderate Use Cases

5.1 Human-Readable Sizes: -h

Raw byte counts are hard to read at a glance. The -h flag (short for human) turns them into K, M, and G. It only changes sizes, so you combine it with -l:

$ ls -lh
-rw-r--r--  1 peter staff  1.2K May 28 17:02 notes.txt
-rw-r--r--  1 peter staff   45M May 30 11:20 video.mp4

The combination ls -lh is probably the single most-typed ls command on the planet. Read it as: "list, with details, in sizes I can actually read".

5.2 Combining Flags

Because Unix flags are single letters, you can stack them behind one dash. The following three commands are identical:

$ ls -l -a -h
$ ls -lah
$ ls -alh        # the order of the letters does not matter

Most Linux users type ls -lah ("long, all, human") as a single word, without thinking about the separate letters. It is worth learning it that way too.

5.3 Sorting

By default ls sorts by name. Several flags change that:

FlagSorts byTypical use
-t Time (newest first) "What did I just change?"
-S Size (largest first) "What is eating my disk?"
-X Extension Group files by type
-v Version / natural order Puts file2 before file10
-r Reverse any sort Combine with the flags above

In practice:

$ ls -lt          # newest at the top
$ ls -ltr         # newest at the BOTTOM, great in a busy log folder
$ ls -lhS         # biggest files first, sizes readable

The command ls -ltr is a sysadmin classic. The most recently changed file ends up on the last line, right above your prompt, where it is easiest to read.

5.4 Marking Types: -F

The -F flag (called classify) appends a small symbol to each name so you can tell the types apart without using -l:

$ ls -F
Documents/   script.sh*   notes.txt   link@
SuffixMeans
/ Directory
* Executable file
@ Symbolic link
| Named pipe (FIFO)

5.5 The Directory Itself: -d

Normally ls Documents dives inside the folder and lists its contents. The -d flag (short for directory) tells ls to show the directory's own entry instead:

$ ls -ld Documents
drwxr-xr-x  2 peter staff  4096 Jun  1 09:14 Documents

The same trick lists only matching items. To see just the directories in the current folder, and not their contents, run:

$ ls -d */

5.6 Colour

Most distributions set up ls so that directories, links, and executables appear in different colours automatically. This is done with a small option:

$ ls --color=auto      # GNU / Linux
$ ls -G                # BSD / macOS

The colours come from the LS_COLORS environment variable. They are a display nicety only. When you pipe ls into another command, the colour codes disappear, which is exactly what you want.

Back to top

6. Advanced Use Cases

6.1 Reading the Permission String

The first column of ls -l packs a lot of information into ten characters. Read it in four chunks:

 -    rwx    r-x    r--
 |     |      |      |
type owner  group  others

The first character is the file type. The next nine are three groups of rwx (read, write, execute) for the owner, the group, and everyone else. A dash means the permission is absent. So rwxr-xr-- reads as: the owner can do everything, the group can read and run, and others can only read.

The very first character tells you what kind of thing each entry is:

CharacterType
- Regular file
d Directory
l Symbolic link
c Character device (for example a terminal)
b Block device (for example a disk)
p Named pipe (FIFO)
s Socket

You can see the rarer types in the /dev directory:

$ ls -l /dev | head
crw-rw-rw-  1 root root 1, 3 Jun  2 08:00 null
brw-rw----  1 root disk 8, 0 Jun  2 08:00 sda

Running this once makes the Unix idea that "everything is a file" suddenly click.

6.2 Recursive Listing: -R

The -R flag (short for recursive) walks into every subdirectory and lists it too:

$ ls -R Documents
Documents:
invoices  letters  notes.txt

Documents/invoices:
2025.pdf  2026.pdf

Documents/letters:
draft.md

Be careful: ls -R / tries to list your entire filesystem. Always pair -R with a path you actually mean. For real searching, find is the better tool.

6.3 Globbing: The Shell Does the Matching

When you type ls *.txt, it is the shell, not ls, that expands *.txt into a list of matching names before ls ever runs.

$ ls *.txt           # all .txt files in this directory
$ ls Doc*            # anything starting with "Doc"
$ ls report-?.md     # ? matches exactly one character
$ ls *.{jpg,png}     # brace expansion: jpg AND png

The command ls itself has no idea what * means. That is why ls *.txt reports "No such file" when nothing matches: there was simply nothing for the shell to hand to ls.

6.4 Piping ls Into Other Tools

Because ls just prints text, it composes neatly with the rest of the Unix toolbox. This is where everyday administration work happens:

$ ls | wc -l                 # count the items in a directory
$ ls -lt | head              # the 10 most recently changed
$ ls -lhS | head             # the biggest files
$ ls -1 | grep -i invoice    # filter the listing

One warning: parsing ls output inside scripts is fragile, because filenames can contain spaces and even newlines. For scripting, prefer shell globs (for f in *.txt) or find -print0. For interactive use at the keyboard, piping ls is perfectly fine.

6.5 The Aliases Everyone Makes

Almost every Linux user defines a few shortcuts in ~/.bashrc:

alias ll='ls -lh'
alias la='ls -lah'
alias l='ls -CF'

After that, typing ll gives you the long, human-readable listing without thinking. You can check what an alias does with type ll. To run the real, unaliased command (for example to get clean output for a pipe), put a backslash in front of it or use command:

$ alias ls                 # often: alias ls='ls --color=auto'
$ \ls                      # run the real ls, ignoring the alias
$ command ls               # the same, more explicitly
Back to top

7. Something Most Users Do Not Know

7.1 Inodes and the -i Flag

Here is the detail that surprises even experienced users. A file is not really its name. Underneath, every file is an inode: a numbered record that holds the file's metadata and points to the actual data on disk. The name you see is just a label that points at an inode.

The -i flag shows that hidden inode number:

$ ls -li
1310721 -rw-r--r--  1 peter staff  1234 May 28 17:02 notes.txt
1310722 -rw-r--r--  2 peter staff   512 May 28 17:05 original.txt
1310722 -rw-r--r--  2 peter staff   512 May 28 17:05 hardlink.txt

Look closely: original.txt and hardlink.txt share the same inode number, 1310722, and both show a link count of 2. They are two names for the exact same file. This is what a hard link is, and it is why the link-count column in ls -l suddenly makes sense.

7.2 The Other Timestamps

Most people think a file has one date. In fact every file carries three times, and ls -l only shows one of them by default:

FlagShowsMeaning
(default) mtime Content last modified
-lu atime Content last accessed
-lc ctime Metadata last changed

You can also ask for the full, precise timestamp instead of the short date:

$ ls -l --time-style=full-iso notes.txt
-rw-r--r-- 1 peter staff 1234 2026-05-28 17:02:41.000000000 +0200 notes.txt

Many people never realise that ls -lu and ls -lc exist. When you are debugging "when was this file really touched?", these are the keys.

7.3 Knowing Where ls Stops

Part of expertise is knowing when a tool is the wrong one. The command ls -l is a quick summary; for the full record of a single file, reach for stat:

NeedUseWhy
Searching a tree find Filters by name, size, time, and type
Metadata of one file stat Shows all three times, the inode, and blocks
A directory tree view tree Draws an indented tree

There are also modern, prettier replacements such as eza (formerly exa) and lsd, which add colours, icons, and git status. They are pleasant, but learn ls first: it is installed on every machine you will ever log in to, including a bare container, a rescue shell, or a twenty-year-old server. The fancy tools are a luxury; ls is a guarantee.

Back to top

8. Best Practices

  • Look before you act. Run ls before you copy, move, or delete. It is read-only and cannot hurt anything, so use it freely to confirm you are in the right place.
  • Learn two combinations by heart. Internalise ls -lah (everything, with readable sizes) and ls -ltr (oldest to newest, newest at the bottom). Together they cover the vast majority of daily needs.
  • Use -d */ to list folders only when a directory is crowded with files.
  • Do not parse ls in scripts. For automation, use shell globs (for f in *.log) or find -print0. Save ls for interactive use.
  • Reach for the manual without hesitation. The habit that separates beginners from professionals is not memorising every flag; it is typing man ls the moment a question comes up.
$ man ls                            # the full manual page
$ ls --help                         # a quick flag summary (GNU)
$ info coreutils 'ls invocation'    # the verbose GNU manual
Back to top

9. Common Mistakes

9.1 Three Common Myths

MythReality
"Colour is built into ls." It is usually a shell alias. Run \ls and the colour disappears.
"ls is a Linux command." It is a Unix command, about twenty years older than Linux.
"ls -l shows everything." It hides dotfiles. You need ls -la to see them.

9.2 Other Traps to Avoid

  • Forgetting -a. If a configuration file "is missing", it is probably a hidden dotfile. Check with ls -la before you conclude anything.
  • Running ls -R / by accident. This tries to walk your whole filesystem and floods the terminal. Always give -R a specific path.
  • Trusting a glob that matched nothing. When ls *.txt says "No such file", it means the shell found no matches, not that ls is broken.
  • Assuming the date is the modification date. If a backup or sync tool touched a file, you may want the access time (-lu) or the metadata-change time (-lc) instead.
  • Letting an alias leak into a pipe. If a script behaves strangely, an alias may be adding flags or colours. Use \ls or command ls to get the raw output.
Back to top

10. Summary

The ls command looks tiny, but it is a complete window into how Linux works.

  • ls means "list". It dates back to Unix in 1971, with roots in Multics before that, and runs on every Unix-like system today.
  • It is read-only and safe, which makes it the perfect command to explore an unfamiliar system with.
  • -a reveals hidden files, -l gives the long format, and -h makes sizes readable. ls -lah combines all three.
  • The long format's first column encodes the file type and permissions, for example drwxr-xr-x.
  • Sort with -t (time), -S (size), and -r (reverse). The combination ls -ltr is the everyday classic.
  • Go deeper with -R (recursive), -i (inodes, which explain hard links), -d (the directory itself), and the -u / -c alternate times.
  • Globbing such as ls *.txt is done by the shell, not by ls. And ls composes cleanly with wc, head, and grep.
  • Know where ls stops: find for searching, stat for one file, and tree for a tree view.
  • When in doubt, type man ls.

This is the quick reference worth keeping:

ls           show what is here
ls -a        include hidden files
ls -lh       details with readable sizes
ls -lah      all of the above at once
ls -ltr      oldest to newest (newest at the bottom)
ls -lhS      biggest files first
ls -ld */    only the directories, themselves
ls -li       with inode numbers (and spot hard links)
ls -R DIR    recursively, into every subfolder
Back to top
Linux command: ls
Peter Martin
Peter Martin

Joomla specialist and Linux admin for fast, secure and scalable websites.