# ls

_Peios / Using Peios / Peiosutils / Listing and paths_

> List the contents of a directory — the default listing, the Peios long format and its security-descriptor columns, and the sorting and formatting options.

`ls` lists the contents of a directory. It is the command you use 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`](#choosing-what-to-list).
- **Entries are sorted by name.** Alphabetical order, case-sensitive. Other [sort orders](#sorting) 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](/peios/security-fundamentals/access-decisions/overview.md) 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](/peios/security-fundamentals/security-descriptors/inheritance.md).

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`](/peios/using-peios/peiosutils/listing-and-paths/stat.md) or the dedicated security tooling. The concepts are in [Security descriptors](/peios/security-fundamentals/security-descriptors/overview.md).

### 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](/peios/security-fundamentals/identity/sids.md). For what "owner" means and what it grants, see [Ownership](/peios/security-fundamentals/security-descriptors/ownership.md).

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, `\|` for a FIFO, `=` for a socket, and `*` for an executable file. |
| `--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`](/peios/using-peios/peiosutils/listing-and-paths/dircolors.md) 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. |

## Symbolic links

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`](/peios/using-peios/peiosutils/listing-and-paths/readlink.md) and [`realpath`](/peios/using-peios/peiosutils/listing-and-paths/realpath.md) 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. |

Related content:

- [Listing and paths](/peios/using-peios/peiosutils/listing-and-paths/overview.md)
- [stat](/peios/using-peios/peiosutils/listing-and-paths/stat.md)
- [dircolors](/peios/using-peios/peiosutils/listing-and-paths/dircolors.md)
- [Security descriptors](/peios/security-fundamentals/security-descriptors/overview.md)
- [Inheritance](/peios/security-fundamentals/security-descriptors/inheritance.md)
