Linux ls Command
last modified October 23, 2026
The ls (list) command lists the contents of directories and
shows information about files: their type, permissions, owner, size, and
modification time. It is one of the most frequently used commands on
Linux.
The syntax is ls [options] [file...]. Without arguments,
ls lists the current directory. The examples use GNU
ls from coreutils 9.1 in the en_US.UTF-8 locale,
run in a sample project directory that contains regular files, hidden
files, an executable script, a symbolic link, and two subdirectories.
Listing a directory
Without options, ls prints the names of the files in the
current directory, sorted alphabetically. Hidden files are not shown.
ls ls src docs
When the output does not go to a terminal (here, it goes to a file), GNU
ls prints one name per line. The sort order follows the locale:
case and punctuation are ignored in the first comparison, so
README.md sorts between readme-link and
src, and file10.txt comes before
file1.txt. Run LC_ALL=C ls for plain byte order,
which puts uppercase names first. With several directory arguments, each
listing gets a header.
$ ls backup.tar.gz build.sh data.csv docs file10.txt file1.txt file2.txt logo.png my notes.txt notes.txt readme-link README.md src $ ls src docs docs: guide.md src: lib main.c util.c
Columns and one name per line
In a terminal, ls arranges names in columns. The
-C option forces columns and -1 forces one name
per line, regardless of where the output goes.
ls -C -w 60 ls | head -n 3
The -w option sets the line width; by default, ls
uses the width of the terminal. When the output is piped, as in the second
command, ls automatically switches to one name per line, so
scripts can process the names line by line.
$ ls -C -w 60 backup.tar.gz docs file2.txt notes.txt src build.sh file10.txt logo.png readme-link data.csv file1.txt my notes.txt README.md $ ls | head -n 3 backup.tar.gz build.sh data.csv
Long listing format
The -l option shows details about each file.
ls -l
The first column is the file type (- regular file,
d directory, l symbolic link) followed by the
permissions. Then come the number of
hard links, the owner, the group, the size in bytes, the modification time,
and the name. For a symbolic link, the target is shown after
->. Files modified more than six months ago show the year
instead of the time. The total line is the disk space used by
the listed files in 1 KiB blocks; it is smaller than the sum of the sizes
because backup.tar.gz is a sparse file.
$ ls -l total 2528 -rw-r--r-- 1 jano jano 12582912 Jan 10 2026 backup.tar.gz -rwxr-xr-x 1 jano jano 21 Jun 1 12:00 build.sh -rw-r--r-- 1 jano jano 2411724 Oct 22 21:40 data.csv drwxr-xr-x 2 jano jano 4096 Oct 1 10:00 docs -rw-r--r-- 1 jano jano 0 May 5 10:00 file10.txt -rw-r--r-- 1 jano jano 0 May 5 10:00 file1.txt -rw-r--r-- 1 jano jano 0 May 5 10:00 file2.txt -rw-r--r-- 1 jano jano 153600 Sep 2 08:15 logo.png -rw-r--r-- 1 jano jano 0 May 5 10:00 my notes.txt -rw-r--r-- 1 jano jano 5 Oct 20 18:05 notes.txt lrwxrwxrwx 1 jano jano 9 May 5 10:00 readme-link -> README.md -rw-r--r-- 1 jano jano 10 Mar 14 2026 README.md drwxr-xr-x 3 jano jano 4096 Oct 1 10:00 src
Hidden files
Files whose names start with a dot are hidden. The -a option
shows all files; -A shows all except . and
...
ls -a ls -A
The entries . (the directory itself) and .. (its
parent) exist in every directory, so -A is usually the more
useful option. Hidden files are typically configuration files such as
.gitignore and .env.
$ ls -a . .. backup.tar.gz build.sh data.csv docs .env file10.txt file1.txt file2.txt .gitignore logo.png my notes.txt notes.txt readme-link README.md src $ ls -A backup.tar.gz build.sh data.csv docs .env file10.txt file1.txt file2.txt .gitignore logo.png my notes.txt notes.txt readme-link README.md src
Human-readable sizes
The -h option prints sizes with unit suffixes. It is used
together with -l.
ls -lh logo.png data.csv backup.tar.gz ls -l --si logo.png data.csv backup.tar.gz
-h uses powers of 1024, so 150K means 150 KiB
(153,600 bytes). The --si option uses powers of 1000, which is
how storage vendors count; the same file is 154k.
$ ls -lh logo.png data.csv backup.tar.gz -rw-r--r-- 1 jano jano 12M Jan 10 2026 backup.tar.gz -rw-r--r-- 1 jano jano 2.3M Oct 22 21:40 data.csv -rw-r--r-- 1 jano jano 150K Sep 2 08:15 logo.png $ ls -l --si logo.png data.csv backup.tar.gz -rw-r--r-- 1 jano jano 13M Jan 10 2026 backup.tar.gz -rw-r--r-- 1 jano jano 2.5M Oct 22 21:40 data.csv -rw-r--r-- 1 jano jano 154k Sep 2 08:15 logo.png
Sorting by modification time
The -t option sorts by modification time, newest first. The
-r option reverses any sort order.
ls -lt ls -ltr | tail -n 3
ls -ltr lists the most recently modified files at the end,
where they stay visible in a long listing. Piping it to tail
shows only the latest changes. Files with the same time are sorted by name.
$ ls -lt total 2528 -rw-r--r-- 1 jano jano 2411724 Oct 22 21:40 data.csv -rw-r--r-- 1 jano jano 5 Oct 20 18:05 notes.txt drwxr-xr-x 2 jano jano 4096 Oct 1 10:00 docs drwxr-xr-x 3 jano jano 4096 Oct 1 10:00 src -rw-r--r-- 1 jano jano 153600 Sep 2 08:15 logo.png -rwxr-xr-x 1 jano jano 21 Jun 1 12:00 build.sh -rw-r--r-- 1 jano jano 0 May 5 10:00 file10.txt -rw-r--r-- 1 jano jano 0 May 5 10:00 file1.txt -rw-r--r-- 1 jano jano 0 May 5 10:00 file2.txt -rw-r--r-- 1 jano jano 0 May 5 10:00 my notes.txt lrwxrwxrwx 1 jano jano 9 May 5 10:00 readme-link -> README.md -rw-r--r-- 1 jano jano 10 Mar 14 2026 README.md -rw-r--r-- 1 jano jano 12582912 Jan 10 2026 backup.tar.gz $ ls -ltr | tail -n 3 drwxr-xr-x 2 jano jano 4096 Oct 1 10:00 docs -rw-r--r-- 1 jano jano 5 Oct 20 18:05 notes.txt -rw-r--r-- 1 jano jano 2411724 Oct 22 21:40 data.csv
Sorting by size
The -S option sorts by file size, largest first.
ls -lSh | head -n 5
This is a quick way to find the largest files in a directory. Note that
ls reports the size of a directory entry (4.0K), not the size
of its contents; use du for that.
$ ls -lSh | head -n 5 total 2.5M -rw-r--r-- 1 jano jano 12M Jan 10 2026 backup.tar.gz -rw-r--r-- 1 jano jano 2.3M Oct 22 21:40 data.csv -rw-r--r-- 1 jano jano 150K Sep 2 08:15 logo.png drwxr-xr-x 2 jano jano 4.0K Oct 1 10:00 docs
Natural and extension sort
The -v option sorts numbers within names by their value. The
-X option sorts by extension.
ls file* ls -v file* ls -X
In the default order, file10.txt comes before
file1.txt; with -v, the numbers are compared as
numbers. With -X, names without an extension come first,
followed by groups such as .csv, .gz,
.md, and .png. The --sort option
selects any order by word, for example --sort=size.
$ ls file* file10.txt file1.txt file2.txt $ ls -v file* file1.txt file2.txt file10.txt $ ls -X docs readme-link src data.csv backup.tar.gz README.md logo.png build.sh file10.txt file1.txt file2.txt my notes.txt notes.txt
File type indicators
The -F (--classify) option appends a character
that shows the file type.
ls -F
A slash marks a directory, * an executable file, and
@ a symbolic link. Other indicators are | for a
named pipe and = for a socket. This is useful when colours are
not available.
$ ls -F backup.tar.gz build.sh* data.csv docs/ file10.txt file1.txt file2.txt logo.png my notes.txt notes.txt readme-link@ README.md src/
Listing a directory itself
When a directory is given as an argument, ls lists its
contents. The -d option lists the directory entry instead.
ls -l src ls -ld src ls -d */
ls -ld shows the permissions and owner of the directory. The
pattern */ matches only directories, so ls -d */
lists the subdirectories of the current directory.
$ ls -l src total 4 drwxr-xr-x 2 jano jano 4096 Sep 28 16:20 lib -rw-r--r-- 1 jano jano 0 Sep 28 16:20 main.c -rw-r--r-- 1 jano jano 0 Sep 28 16:20 util.c $ ls -ld src drwxr-xr-x 3 jano jano 4096 Oct 1 10:00 src $ ls -d */ docs/ src/
Recursive listing
The -R option lists subdirectories recursively.
ls -R src docs
Each directory is printed with a header and its contents. For a compact
view of a tree, the tree command is easier to read; for
searching, use find.
$ ls -R src docs docs: guide.md src: lib main.c util.c src/lib: list.c
Inode numbers and symbolic links
The -i option shows the inode number of each file. The
-L option shows information about the target of a symbolic
link instead of the link.
ls -i README.md notes.txt readme-link ls -lL readme-link
The link readme-link has its own inode. With -L,
ls follows the link and shows the size, permissions, and date
of README.md. Hard links to the same file share an inode
number; see the ln command article.
$ ls -i README.md notes.txt readme-link 2628410 notes.txt 2628419 readme-link 2628397 README.md $ ls -lL readme-link -rw-r--r-- 1 jano jano 10 Mar 14 2026 readme-link
Time formats
The --time-style option controls how the modification time is
printed.
ls -l --time-style=long-iso README.md data.csv ls -l --time-style=+'%d.%m.%Y %H:%M' README.md data.csv ls -l --full-time README.md
long-iso always prints the full date and time, which avoids
the six-month rule of the default format. A + introduces a
custom format with the same directives as the
date command. --full-time
shows nanoseconds and the time zone offset.
$ ls -l --time-style=long-iso README.md data.csv -rw-r--r-- 1 jano jano 2411724 2026-10-22 21:40 data.csv -rw-r--r-- 1 jano jano 10 2026-03-14 09:30 README.md $ ls -l --time-style=+'%d.%m.%Y %H:%M' README.md data.csv -rw-r--r-- 1 jano jano 2411724 22.10.2026 21:40 data.csv -rw-r--r-- 1 jano jano 10 14.03.2026 09:30 README.md $ ls -l --full-time README.md -rw-r--r-- 1 jano jano 10 2026-03-14 09:30:00.000000000 +0100 README.md
Numeric IDs and shorter listings
The -n option shows numeric user and group IDs. The
-o option omits the group column, and -g the
owner column.
ls -ln README.md ls -lo README.md
Numeric IDs are useful for files that belong to deleted users or come from another system, for example from an archive or a mounted disk.
$ ls -ln README.md -rw-r--r-- 1 1000 1000 10 Mar 14 2026 README.md $ ls -lo README.md -rw-r--r-- 1 jano 10 Mar 14 2026 README.md
Names with special characters
Quoting options make names with spaces and other special characters unambiguous.
ls -1 my* notes.txt ls -1Q my* notes.txt ls -1 --quoting-style=shell-escape my* notes.txt
In a terminal, GNU ls quotes such names automatically. The
-Q option puts every name in double quotes, while
shell-escape quotes only the names that need it, in a form
that can be pasted into a shell command. The output of ls is
meant for people; in scripts, use globs (for f in *.txt) or
find instead of parsing it.
$ ls -1 my* notes.txt my notes.txt notes.txt $ ls -1Q my* notes.txt "my notes.txt" "notes.txt" $ ls -1 --quoting-style=shell-escape my* notes.txt 'my notes.txt' notes.txt
Aliases and colours
Many distributions define aliases for common ls option
combinations in ~/.bashrc.
alias ll='ls -alFh' ll src
The ll alias combines a long listing with hidden files, type
indicators, and human-readable sizes. Default ~/.bashrc files
also define alias ls='ls --color=auto', which colours names by
type when the output is a terminal. The colours are configured with the
LS_COLORS variable, usually set by dircolors.
$ alias ll='ls -alFh' $ ll src total 12K drwxr-xr-x 3 jano jano 4.0K Oct 1 10:00 ./ drwxr-xr-x 4 jano jano 4.0K Oct 23 13:23 ../ drwxr-xr-x 2 jano jano 4.0K Sep 28 16:20 lib/ -rw-r--r-- 1 jano jano 0 Sep 28 16:20 main.c -rw-r--r-- 1 jano jano 0 Sep 28 16:20 util.c
Best practices for ls
- Use ls -ltr to find recent changes: The newest files appear at the bottom.
- Use -d for directories:
ls -ld dirshows the directory's own permissions. - Don't parse ls in scripts: Use globs,
find, orstatfor reliable file handling. - Use long-iso times in reports: They are unambiguous and sort correctly.
- Define aliases: Keep favourite combinations such as
llin~/.bashrc.
Source
In this article, we have used the ls command to list
directories, show file details, display hidden files, sort by time, size,
and version, and format names and times.
Author
List all Linux tutorials.