ZetCode

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

Source

GNU ls manual

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

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Linux tutorials.