These docs are under active development and cover the v0.20 Kobicha security model.
On this page
reference 10 min read

ls

ls lists the contents of a directory. It is the command you reach for to answer "what is in here?" — and, with the right options, "who owns these files, how big are they, and when were they last changed?".

ls [options] [file...]

Each file is a directory to list the contents of, or a single file to report on. With no file argument, ls lists the directory you are currently in.

$ ls
build.sh  notes.txt  projects

The default listing

Run on its own, ls prints the names of the entries in a directory and nothing else. Three rules shape that default:

  • Hidden entries are skipped. A name beginning with a dot (.config, .cache) is hidden. ls leaves hidden entries out unless you ask for them with -a or -A.
  • Entries are sorted by name. Alphabetical order, case-sensitive. Other sort orders are available.
  • The layout adapts to where output goes. When ls is writing to a terminal it arranges names into columns sized to the terminal width. When output is redirected to a file or a pipe it prints one name per line, so the result is easy for another program to read.

Everything past this default is opt-in. The rest of this page is the options, grouped by what they do.

The long format

-l (or --long) switches ls into the long format: one entry per line, each with its mode, owner, size, modification time, and name.

$ ls -l
total 28
d-- S-1-5-21-9f3a-1c4e-7b20-1001   4096 May 14 09:12 projects
-x- S-1-5-21-9f3a-1c4e-7b20-1001   8344 May 16 17:40 build.sh
--- S-1-5-21-9f3a-1c4e-7b20-1001    219 May 15 11:03 notes.txt
--+ S-1-5-18                      12048 May 10 22:15 policy.db

The total line at the top reports the combined disk space used by the listed files, measured in blocks.

Each entry line has five columns: mode, owner, size, modification time, name. There is no permission-bits column and no group column — the reason is below.

The mode column

The mode column is three characters: [type][executable][protected].

The first character is the file's type:

Character Type
- Regular file
d Directory
l Symbolic link
p Named pipe (FIFO)
s Socket
c Character device
b Block device

The second character is the executable mark. It is x when the entry is a regular file that is marked as an executable, and - otherwise (it is always - for directories, links, and other non-regular entries).

The executable mark describes the file, not your relationship to it. x means "this file is runnable code." It does not mean that you, specifically, are allowed to run it — whether a given principal may execute a file is a separate access decision made against the file's security descriptor. A file can show x and still be one you cannot run, and the reverse. See Access decisions for how execution is actually authorised.

The third character is the protected mark. It is + when the file's access control is inheritance-protected, and - otherwise.

A - here means the file's access control is inherited from the directory it lives in: it tracks its parent. A + means the file's access control has been set deliberately and locked, so it no longer tracks the parent directory. The + is the signal that someone has tailored this file's security on purpose. See Inheritance.

So in the example above: projects is a directory (d--); build.sh is an executable file (-x-); notes.txt is an ordinary file inheriting its security from its directory (---); and policy.db is an ordinary file whose access control has been protected (--+).

Why there are no permission bits

A long listing does not carry a fixed block of permission characters. On Peios, what a principal may do to a file is decided by the file's security descriptor — a record that can contain any number of entries granting or denying specific rights to specific principals. There is no small, fixed set of bits that captures that, so ls -l does not pretend there is.

The mode column tells you the file's type and two facts about it (is it executable, is its security protected). To see who may do what, look at the security descriptor itself with stat or the dedicated security tooling. The concepts are in Security descriptors.

The owner column

The owner column is the SID of the file's owner — shown in full, in the S-1-… form. ls does not translate SIDs into account names; it prints the identifier exactly as the security descriptor stores it. A well-known owner such as the system itself appears as its fixed SID (S-1-5-18); an ordinary account appears as a longer domain-style SID.

For what a SID is and how to read one, see SIDs. For what "owner" means and what it grants, see Ownership.

If ls cannot read a file's descriptor — for a dangling symlink, say — the owner column shows ? and the mode column shows the type character followed by ??.

Choosing what to list

By default ls shows non-hidden entries, and for a directory argument it shows the directory's contents. These options change that.

Option Effect
-a, --all Show hidden entries too, including . (the directory itself) and .. (its parent).
-A, --almost-all Show hidden entries, but leave out . and ...
-d, --directory List a directory as an entry in its own right, instead of listing its contents. Useful with -l to see a directory's own owner and mode.
-R, --recursive Descend into every subdirectory and list it too.
-B, --ignore-backups Skip entries whose name ends in ~.
--ignore=PATTERN Skip entries whose name matches the shell pattern. May be given more than once.
--hide=PATTERN Like --ignore, but overridden by -a or -A — so a hide rule can be cancelled by asking to see everything.

Sorting

ls sorts by name by default. These options change the sort key; -r reverses whatever order is in effect.

Option Sort order
-t By modification time, newest first.
-S By size, largest first.
-X By file extension, alphabetically.
-v By version: runs of digits in the name sort numerically, so f2 comes before f10.
-U No sorting at all — entries appear in the order the directory stores them. Fast for very large directories.
-r, --reverse Reverse the current sort.
--sort=WORD Choose the sort key by name: none, time, size, extension, version, or width.
--group-directories-first List directories before other entries, with each group sorted normally.

Output layout

When several entries fit on a line, ls has to decide how to arrange them.

Option Layout
-C Columns, filled top-to-bottom. The default when writing to a terminal.
-x Columns, filled left-to-right (across the rows) instead.
-1 One entry per line. The default when output is not a terminal.
-m All entries on as few lines as possible, separated by commas.
-l, --long The long format described above.
--format=WORD Choose the layout by name: across, commas, horizontal, long, single-column, or vertical.
-w, --width=COLS Assume the terminal is COLS columns wide instead of detecting it. 0 means unlimited.

File-type indicators and colour

These options make a listing easier to scan by marking entries with a symbol or a colour.

Option Effect
-F, --classify Append a type symbol to each name: / for a directory, @ for a symlink, `
--file-type The same, but without the * on executables.
-p Append only the / on directories.
--indicator-style=WORD Choose the indicator set: none, slash, file-type, or classify.
--color[=WHEN] Colour entries by type. WHEN is auto (colour only when writing to a terminal — the usual choice), always, or never.

The colours ls uses are configurable. dircolors generates the colour settings and explains how to install them.

File sizes

In the long format, and with -s, sizes are printed in bytes by default. These options rescale them.

Option Effect
-h, --human-readable Print sizes with a unit suffix — 4.0K, 234M, 56G — using powers of 1024.
--si Like -h, but using powers of 1000, so the suffixes are decimal.
-s, --size Print the disk space each entry occupies, in blocks, before its name.
-k, --kibibytes Use 1024-byte blocks for the size figures and directory totals.
--block-size=SIZE Scale every size by SIZE (for example --block-size=1M to count in megabytes).

Timestamps

The long format shows the modification time by default. These options change which timestamp is shown — and, when sorting by time, which one is sorted on.

Option Timestamp
-u Access time — when the file was last read.
-c Status-change time — when the file's metadata last changed.
--time=WORD Choose the timestamp by name: atime/access, ctime/status, mtime/modification, or birth/creation.
--time-style=STYLE Choose the date format: full-iso, long-iso, iso, locale, or +FORMAT for a custom layout.
--full-time Shorthand for the long format with --time-style=full-iso — a complete, unabbreviated timestamp.

By default ls reports on a symbolic link itself — its type is l, its size is the length of the link text. These options make it report on the link's target instead.

Option Effect
-L, --dereference Always report on the file a link points to, not the link.
-H, --dereference-command-line Dereference only the links named directly on the command line, not links found inside a listed directory.
--dereference-command-line-symlink-to-dir Dereference a command-line link only when it points to a directory.

readlink and realpath are the dedicated tools for inspecting and resolving links.

Other options

The long-tail options, each in one line.

Option Effect
-i, --inode Print each entry's index number (its inode number).
-Z, --context Print each entry's security context. Available only when the build enables it.
-b, --escape Print non-printable characters in names using C-style backslash escapes.
-q, --hide-control-chars Replace non-printable characters in names with ?. The default when writing to a terminal.
--show-control-chars Print names verbatim, control characters and all.
-N, --literal Print names exactly, with no quoting.
-Q, --quote-name Wrap each name in double quotes.
--quoting-style=WORD Choose the quoting scheme: literal, shell, shell-always, shell-escape, c, escape, and others.
-T, --tabsize=COLS Assume tab stops every COLS columns when laying out output.
-f List everything, unsorted, including hidden entries — equivalent to -aU. Also turns colour off unless --color is given explicitly.
--hyperlink[=WHEN] Emit terminal hyperlinks for file names, so a capable terminal can make them clickable.
-D, --dired Emit extra position markers designed for the Emacs dired editing mode.
--zero End each line with a NUL character instead of a newline, and list one entry per line.

Exit status

Code Meaning
0 Success — everything requested was listed.
1 A minor problem — for example, a named file could not be accessed. The rest of the listing still printed.
2 A serious problem — for example, a directory could not be read, or an option was invalid.