The Filesystem and Navigation · about 30 min

The directory tree

Why this matters

Every command you run takes file names, and every script reads or writes files somewhere. On Windows you may be used to drive letters (C:\, D:\); Unix has none. Instead there is one single tree of directories, and disks, USB sticks, network shares and even the kernel's own status information are attached to branches of it. Once you know the layout, you can find your way around any Linux machine, server or container, because they all follow the same plan.

One tree, starting at /

The top of the tree is the root directory, written as a single slash: /. Every file and directory on the system is somewhere below it. A path names a location by listing the directories you pass through, separated by slashes:

/                         the root directory
├── bin -> usr/bin        programs (on modern systems a link to /usr/bin)
├── dev                   device files: disks, terminals, /dev/null
├── etc                   system configuration (text files)
│   ├── apt
│   ├── hostname
│   └── passwd
├── home                  users' home directories
│   └── learner           your home directory, also written ~
├── proc                  live information about processes and the kernel
├── root                  the administrator's home directory
├── tmp                   temporary files, writable by everyone
├── usr                   installed software (read-only in normal use)
│   ├── bin               most programs: ls, grep, bash ...
│   ├── lib               libraries
│   └── share             architecture-independent data: man pages, docs
├── var                   variable data: logs, caches, spools
│   └── log
└── work                  this sandbox only: your lesson workspace

Open the shell for this lesson and look:

$ ls /
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr  work

This layout is described by the Filesystem Hierarchy Standard and, on your system, by man 7 hier. The details vary a little between distributions, but /etc, /home, /tmp, /usr and /var mean the same thing everywhere.

Note the two different meanings of the word "root": the root directory /, and the root user (the administrator, whose home is /root). Module 4 covers the user.

Absolute and relative paths

A path that starts with / is absolute: it is followed from the root, and means the same thing wherever you are. /etc/hostname is always the same file.

A path that does not start with / is relative: it is followed from the current directory of the process. If your current directory is /etc, then apt/sources.list.d means /etc/apt/sources.list.d. If you are in /work, the same relative path means /work/apt/sources.list.d, which probably does not exist.

$ pwd
/work
$ ls /etc/apt
apt.conf.d  auth.conf.d  keyrings  preferences.d  sources.list.d  trusted.gpg.d
$ ls etc/apt
ls: cannot access 'etc/apt': No such file or directory

The second ls looked for /work/etc/apt. The error message tells you the path it tried; when a file "is not there", the first question is always "relative to what?".

Every directory contains two special entries: . (the directory itself) and .. (its parent). So .. from /work is /, and /usr/bin/.. is /usr. The root's parent is the root itself. You will use these constantly in the next lesson.

What happens underneath: path resolution

When a program opens /etc/apt/sources.list, it hands the whole string to the kernel. The kernel resolves it one component at a time:

"/etc/apt/sources.list"
 start at the root directory
 look up "etc" in it        → a directory
 look up "apt" in that      → a directory
 look up "sources.list"     → a file: open it

For a relative path, the kernel starts at the process's current directory instead of the root. That is the whole difference, and it is why each process having its own current directory matters. At each step the kernel also checks permissions (module 4): you need permission to pass through every directory on the way.

Directories are really just lists of names, each pointing at the actual file. You will see in module 3 that the name and the file are different things.

Many disks, one tree

A second disk or a USB stick is not a new letter: it is mounted onto an existing directory, called a mount point, and its contents appear there. The mount command (or cat /proc/mounts) shows what is attached where. In this container, /work is actually a directory on the host computer mounted into the container, and /tmp is a tmpfs, a filesystem that lives entirely in memory and disappears when the container stops.

$ df -h /work /tmp
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p3  930G  410G  519G  45% /work
tmpfs           128M     0  128M   0% /tmp

(Your numbers will differ.) df (disk free) shows which filesystem each path is on.

"Everything is a file"

Unix presents many things through the same file interface: open, read, write, close.

$ cat /proc/uptime
5321.47 5280.12
$ cat /proc/sys/kernel/hostname
sandbox
$ ls /proc
1  12  acpi  cmdline  cpuinfo  meminfo  mounts  self  sys  uptime  version ...

The numbered directories in /proc are running processes, by PID. /proc/self is always the process that is reading it. Module 13 explores this.

Because the same tools work on all of these, cat, grep and the rest can inspect hardware and kernel state without special programs.

Text configuration

Most of /etc is human-readable. Try:

$ cat /etc/hostname
sandbox
$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
NAME="Debian GNU/Linux"
VERSION_ID="13"
...
$ head -3 /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin

This is a big part of why the shell is so powerful for administration: the configuration of the whole system is text, and the shell is a text tool.

Common mistakes

Recap

Going further: read man 7 hier. Then run cat /proc/self/status | head twice and notice the Pid: line changes: each cat is a new process.

Exercises

Exercise 1 · quiz

Where does it live?

You want to look at the system-wide configuration of a program installed on a Debian machine (for example, the settings of the package manager apt). Which top-level directory do you look in first?

Answer
  • /etc

/etc holds host-specific configuration, almost all of it plain text files you can read with cat or less. apt's settings are under /etc/apt. /var holds data that changes while the system runs (logs, caches, mail spools), /bin and /usr/bin hold programs, /home holds users' personal files, and /dev holds device files.

Exercise 2 · quiz

Absolute or not?

Which of these paths are absolute, that is, mean the same file no matter what the current directory is? Select all that apply.

Answer
  • /etc/hostname

  • /

  • /home/learner/../learner

A path is absolute exactly when it starts with /. /home/learner/../learner looks odd, but it starts at the root, so it always means the same place (it goes into /home/learner, back up to /home, and down into learner again). etc/hostname and ./notes.txt are relative: they are looked up starting from the current directory of the process that uses them.

Exercise 3 · task in a shell

Name the standard directories

Create the file /work/paths.txt with exactly three lines, each an absolute path:

  1. the directory that holds system-wide configuration files,
  2. the directory that contains the users' home directories,
  3. the directory for temporary files that any user may write to.

You can create the file with three echo commands (use > for the first and >> for the next two; >> appends instead of overwriting), or with the editor nano paths.txt (save with Ctrl-O, Enter; quit with Ctrl-X).

Hint 1

Look at the table of top-level directories in the lesson, or run ls / and ls -ld /tmp.

Hint 2

echo /etc > paths.txt then echo /home >> paths.txt then echo /tmp >> paths.txt.

Reference solution
echo /etc > paths.txt
echo /home >> paths.txt
echo /tmp >> paths.txt

Exercise 4 · task in a shell

Read the system

Two small investigations, both answered by reading files with cat:

  1. Debian records its exact version number in the one-line file /etc/debian_version. Copy that line into /work/debver.txt (for example cat /etc/debian_version > debver.txt).
  2. The kernel exposes information about itself as files under /proc. The file /proc/sys/kernel/ostype contains the name of the kernel. Save its contents into /work/kernel.txt.
Hint 1

cat FILE prints a file; > NAME saves the output into NAME.

Hint 2

cat /proc/sys/kernel/ostype > kernel.txt

Reference solution
cat /etc/debian_version > debver.txt
cat /proc/sys/kernel/ostype > kernel.txt