---
title: 'Navigation Commands'
source: 'https://academia.sh/en/courses/introduction-to-linux/navigation-commands'
course: 'Introduction to Linux'
language: en
updated: '2026-08-17T18:09:56+00:00'
license: 'CC BY-SA 4.0'
---

# Navigation Commands

Changing the working directory, reading the listing output column by column, sorting criteria, and accessing a file's complete metadata.

The previous topic built the `project/` tree and placed a script inside it. Before
working on the tree, it must be possible to **read** it: which files exist, how much
space they take, when they last changed, who owns them.

This lesson decodes the listing output column by column. Reading this output is the
verification tool for every operation done in the rest of the course; the result of
copying, moving, linking, and changing permissions will always be seen in this same
output.

## Changing the Working Directory

The `cd` command changes the working directory and is used in four common forms:

| Command | Effect |
|---|---|
| `cd path` | Switches to the given directory |
| `cd` | Returns to the home directory (no argument) |
| `cd ..` | Goes up one directory |
| `cd -` | Returns to the previous directory and prints its name |

`cd` with no argument reads the home directory from the `HOME` environment variable.
This is a direct use of the environment concept established in the command path
lesson: the home directory is not a value built into the shell, but a setting that
comes from the environment.

## Default Listing

The `ls` command, called with no argument, lists the current directory:

```
$ cd project
$ ls
archive  docs  scripts  data
```

Three behaviors are default: names are sorted, those starting with a dot are not
shown, and the output is split into columns according to terminal width.

The third depends on where the command's output goes:

```
$ ls
archive  docs  scripts  data
$ ls | cat
archive
docs
scripts
data
```

The same command writes in columns if its output goes to a terminal, and one name per
line if it goes to another program. The reason is that column width is meaningless
outside a terminal. This behavior matters for scripts that process the output: trying
to parse the column format is unnecessary, because the script already gets one name
per line.

To also see names starting with a dot, `-a` is given:

```
$ ls -a scripts
.  ..  summary.sh
```

## Long Listing

The `-l` option gives a one-line metadata summary for every file:

```
$ ls -l
total 16
drwxr-xr-x 2 student student 4096 Jul 26 18:47 archive
drwxr-xr-x 2 student student 4096 Jul 26 18:47 docs
drwxr-xr-x 2 student student 4096 Jul 26 18:49 scripts
drwxr-xr-x 4 student student 4096 Jul 26 18:47 data
```

The lines consist of seven fields:

**1. Type and permissions.** The first character is the file type: `-` regular file,
`d` directory, `l` symbolic link, `c` character device, `b` block device. The
remaining nine characters are permission bits and will be decoded in detail in the
permissions topic.

**2. Link count.** The number of directory entries pointing to this file. For
directories this number starts at 2 and each subdirectory adds one: the `data`
directory's value of `4` comes from the two subdirectories inside it. What this
number means will be fully explained in the links lesson.

**3. Owner user.** The file's owner.

**4. Owner group.** The group the file belongs to.

**5. Size.** For regular files, the content size in bytes; for directories, the space
taken by the directory entry table — **not** the total size of the files inside it.

**6. Modification time.** The moment the content was last changed. If older than six
months, the year is shown instead of the time.

**7. Name.**

The `total 16` value in the first line is the number of **blocks** the listed files
occupy; it is not a file count or a byte total. Block size varies by tool and system,
so this number is not comparable across systems.

The size column is in bytes, and it becomes hard to read for large files:

```
$ ls -l /usr/bin/bash
-rwxr-xr-x 1 root root 1543048 Mar 31  2024 /usr/bin/bash
$ ls -lh /usr/bin/bash
-rwxr-xr-x 1 root root 1.5M Mar 31  2024 /usr/bin/bash
```

The `-h` option converts the size into human-readable units. The conversion rounds;
`-h` is not used when the exact byte value is needed.

## Listing the Directory Itself

When given a directory name, `ls` lists the directory's **contents**. To see the
directory's own line, `-d` is needed:

```
$ ls -ld data
drwxr-xr-x 4 student student 4096 Jul 26 18:47 data
```

This distinction is used constantly to verify results in permission and ownership
commands: when a directory's permissions are changed, the line to check is the
directory's own, not those of the files inside it.

When more than one path is given, the output is divided by headers:

```
$ ls -li scripts data
scripts:
total 4
21931 -rwxr-xr-x 1 student student 142 Jul 26 18:49 summary.sh

data:
total 8
21908 drwxr-xr-x 2 student student 4096 Jul 26 18:47 raw
21909 drwxr-xr-x 2 student student 4096 Jul 26 18:47 processed
```

The `-i` option adds a number on the far left: the **inode number**. This number is
the identity, within the file system, of the structure that holds the file's
metadata. It is the identity of the file, not of the name — this distinction is the
foundation of the entire links lesson.

## Sorting

The default sort is by name. To sort by modification time, `-t` is used:

```
$ ls -lt
total 16
drwxr-xr-x 2 student student 4096 Jul 26 18:49 scripts
drwxr-xr-x 2 student student 4096 Jul 26 18:47 archive
drwxr-xr-x 2 student student 4096 Jul 26 18:47 docs
drwxr-xr-x 4 student student 4096 Jul 26 18:47 data
$ ls -ltr
total 16
drwxr-xr-x 4 student student 4096 Jul 26 18:47 data
drwxr-xr-x 2 student student 4096 Jul 26 18:47 docs
drwxr-xr-x 2 student student 4096 Jul 26 18:47 archive
drwxr-xr-x 2 student student 4096 Jul 26 18:49 scripts
```

`-t` puts the newest first; `-r` reverses the order. The `-ltr` combination puts the
newest **last**, and it is the most commonly used form for long listings: the most
recently changed file appears at the bottom without needing to scroll.

For files with the same time, the secondary criterion is name; this keeps the output
stable for the same input.

Other commonly used sorts are the `-S` (by size, largest first) and `-X` (by
extension) options.

## The Full Metadata

`ls -l` is a summary of the metadata. The full set is read with `stat`:

```
$ stat scripts/summary.sh
  File: scripts/summary.sh
  Size: 142       	Blocks: 8          IO Block: 4096   regular file
Device: 0,71	Inode: 21931       Links: 1
Access: (0755/-rwxr-xr-x)  Uid: ( 1001/ student)   Gid: ( 1001/ student)
Access: 2026-07-26 18:49:26.461777000 +0000
Modify: 2026-07-26 18:49:26.458777000 +0000
Change: 2026-07-26 18:49:26.460777000 +0000
 Birth: 2026-07-26 18:49:26.458777000 +0000
```

The output reveals three pieces of information hidden in `ls -l`.

**Permissions are given in two forms at once:** `0755` and `-rwxr-xr-x`. These are the
octal and letter representations of the same value; the conversion between them is
the subject of the permission bits lesson.

**User and group are shown together with their numeric IDs:** `1001/student`. The
value the system stores is the number; the name is resolved from a mapping file.

**There are three separate timestamps:**

- **Access** — the moment the content was last read
- **Modify** — the moment the content was last changed; `ls -l` shows this value
- **Change** — the moment the metadata last changed; a permission or ownership change
  updates this, not the content

The third is often confused with the others. When a file's permissions are changed,
the `ls -lt` ordering does not change, because the time that changes is `Change`, not
`Modify`. This distinction changes the answer to the question "has the file been
touched."

The `Blocks` field gives the number of allocated blocks and does not have to be
proportional to `Size`: a 142-byte file takes up more space on disk because of block
size.

`stat` is not defined in POSIX, and its output format varies by tool family. The
formatting option is `-c` in GNU tools and `-f` in BSD tools; in scripts that need to
be portable, `ls` output or `find` criteria are preferred over `stat`.

## Summary

- By default, `ls` sorts names, skips hidden files, and splits its output into
  columns if it goes to a terminal.
- Long listing gives seven fields: type and permissions, link count, owner, group,
  size, modification time, name.
- For directories, the size column is the size of the directory entry table; it is
  not the total of the contents.
- `-d` shows the directory's own line, `-i` shows the inode number; the inode number
  is the identity of the file, not of the name.
- `-t` sorts by modification time, `-r` reverses it; `-ltr` puts the newest last.
- Metadata has three timestamps: access, content modification, and metadata change.

## Next Step

The tree can be read now, but it is still empty: there is not a single measurement
file in the `raw` directory. The next lesson takes up file creation, copying, and
moving; it shows why these three operations have entirely different costs at the file
system level, and under what conditions they silently lose data.
