
Linux command: ls
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.
Back to topThe right mental model: a directory is just a list of names that point at files.
lsreads that list and shows it to you. Every flag is a different question about that list.
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.
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.
| Era | Milestone |
|---|---|
| ~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.
Back to topA command over fifty years old, still used every day and essentially unchanged in spirit, is proof that good interface design lasts.
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
| Entry | Meaning |
|---|---|
. |
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:
| Column | What 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 |
Back to top
ls -lis the difference between "what is here?" and "tell me everything about what is here".
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:
| Flag | Sorts by | Typical 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@
| Suffix | Means |
|---|---|
/ |
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.
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:
| Character | Type |
|---|---|
- |
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 top7. 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:
| Flag | Shows | Meaning |
|---|---|---|
| (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:
| Need | Use | Why |
|---|---|---|
| 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.
8. Best Practices
- Look before you act. Run
lsbefore 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) andls -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
lsin scripts. For automation, use shell globs (for f in *.log) orfind -print0. Savelsfor interactive use. - Reach for the manual without hesitation. The habit that separates beginners from professionals is not memorising every flag; it is typing
man lsthe 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 top9. Common Mistakes
9.1 Three Common Myths
| Myth | Reality |
|---|---|
"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 withls -labefore you conclude anything. - Running
ls -R /by accident. This tries to walk your whole filesystem and floods the terminal. Always give-Ra specific path. - Trusting a glob that matched nothing. When
ls *.txtsays "No such file", it means the shell found no matches, not thatlsis 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
\lsorcommand lsto get the raw output.
10. Summary
The ls command looks tiny, but it is a complete window into how Linux works.
lsmeans "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.
-areveals hidden files,-lgives the long format, and-hmakes sizes readable.ls -lahcombines 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 combinationls -ltris the everyday classic. - Go deeper with
-R(recursive),-i(inodes, which explain hard links),-d(the directory itself), and the-u/-calternate times. - Globbing such as
ls *.txtis done by the shell, not byls. Andlscomposes cleanly withwc,head, andgrep. - Know where
lsstops:findfor searching,statfor one file, andtreefor 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

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