Linux FilesystemLesson 1 of 8
The tree and how to move in it
Read the single directory tree, then move through it with absolute and relative paths.
pwdlscdreadlinktype
After this lesson you can
- Say what the main top-level directories are for.
- Reach any directory with an absolute path or a relative one.
- Read an ls -l line field by field.
One tree, one root
Linux has a single directory tree. Its top is /, called the root. Every file on the system is somewhere below it, including files on other disks, which are attached to the tree at a directory (lesson 6). There are no drive letters.
You can always ask where you are:
pwd
/home/alex
pwd prints the working directory: the place relative paths start from. Every shell has one.
What lives where
You do not need to memorise the tree, but you do need to know which top-level directories you will touch.
| Directory | What it holds |
|---|---|
/home | One directory per user. Your files and settings. |
/etc | System-wide configuration, as text files. |
/var | Data that changes while the system runs: logs, caches, queues. |
/usr | Installed programs, libraries and shared data. Mostly read-only. |
/tmp | Scratch space. Cleared on reboot, or sooner. |
/opt | Self-contained third-party software. |
/srv | Data served by this machine, such as web or file shares. |
/mnt, /media | Places to attach extra disks by hand or automatically. |
/dev | Device files. Disks, terminals and /dev/null appear here. |
/proc, /sys | Live views of the kernel. Not stored on disk. |
/root | The home directory of the root user. |
List the top level to see them:
ls /
bin boot dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
Absolute and relative paths
A path names a file by walking the tree. There are two ways to write one.
An absolute path starts with / and means the same thing wherever you are:
cd /usr/share/doc
pwd
/usr/share/doc
A relative path does not start with / and starts from the working directory. Three short names make relative paths work:
| Name | Meaning |
|---|---|
. | The current directory |
.. | The parent directory |
~ | Your home directory |
From /usr/share/doc, the parent is /usr/share. Going up twice and into bin reaches /usr/bin:
cd ../../bin
pwd
/usr/bin
cd - returns to the previous directory, which is how you flip between two places:
cd -
/usr/share/doc
With no argument, cd goes home. These four are equivalent when you are alone in your home directory tree: cd, cd ~, cd $HOME and cd /home/alex.
Listing a directory
ls lists the working directory, or whatever you name:
ls /etc/ssh
moduli ssh_config ssh_config.d ssh_host_ed25519_key ssh_host_ed25519_key.pub sshd_config sshd_config.d
The options you will use daily:
| Option | Effect |
|---|---|
-l | Long format: type, permissions, owner, size, date |
-a | Include hidden entries (names starting with .) |
-h | Sizes like 4.0K and 12M (with -l) |
-t | Newest first |
-S | Largest first |
-r | Reverse the order |
-d | Show a directory itself, not its contents |
-R | Recurse into subdirectories |
Combine them: ls -lAht is “long, almost all, human sizes, newest first”.
Reading a long listing
ls -l /etc/hostname /etc/ssh
-rw-r--r-- 1 root root 4 Mar 3 2024 /etc/hostname
/etc/ssh:
total 580
-rw-r--r-- 1 root root 581843 Aug 12 2024 moduli
-rw-r--r-- 1 root root 1649 Aug 12 2024 ssh_config
drwxr-xr-x 2 root root 4096 Aug 12 2024 ssh_config.d
Take the first line apart, left to right:
| Field | Example | Meaning |
|---|---|---|
| Type | - | - file, d directory, l symbolic link |
| Permissions | rw-r--r-- | Owner, group, others (lesson 7) |
| Links | 1 | Number of names for this file (lesson 4) |
| Owner | root | The user who owns it |
| Group | root | The group that owns it |
| Size | 4 | Bytes, or the unit with -h |
| Modified | Mar 3 2024 | Time of the last content change |
| Name | /etc/hostname | And for a link, -> target |
Hidden files
A leading dot hides a name. It is only a convention, and it is how programs keep settings out of the way:
ls -a ~
. .. .bash_history .bash_logout .bashrc .config .profile lab
. and .. are in every directory. ls -A shows hidden entries without those two.
Finding out what a command is
type tells you where a command comes from:
type ls cd pwd
ls is aliased to `ls --color=auto'
cd is a shell builtin
pwd is a shell builtin
For a program on disk, command -v prints its path:
command -v ls
/usr/bin/ls
That is the answer to “where is this installed?”, and it is why PATH matters: the shell searches the directories listed in it, in order.
Practice setup
Exercises in this skill use a scratch directory, ~/lab, so nothing touches your real files. If you have not made it yet:
mkdir -p ~/labPractice
0 of 5 done
Do these on your own system. They get harder. Check each result, then tick it off.
- Warm-up
Know where you are
Print your current directory. Move to
/var/log, print it again, then return to your home directory with a single command that has no argument and print it a third time.Check your result
The last path is your home directory, for example:
/home/alexHint
cdwith no argument goes home.Solution
pwd cd /var/log pwd cd pwd - Warm-up
Hop with a relative path
Go to
/usr/bin. Without typing a path that starts with/, move to/usr/share/doc. Confirm withpwd.Check your result
/usr/share/docHint
Go up one level first, then down.
Solution
cd /usr/bin cd ../share/doc pwd - Practice
Is /bin a real directory?
Use a long listing of the directory entry itself, not its contents, to find out what
/binis on your system. Then print the real location of/bin/sh.Check your result
On a current Debian or Ubuntu system
/binis a link into/usr:lrwxrwxrwx 1 root root 7 Apr 22 2024 /bin -> usr/binreadlink -f /bin/shprints the real file, usually/usr/bin/dash.Hint
ls -dlists a directory itself.readlink -ffollows every link.Solution
ls -ld /bin readlink -f /bin/sh - Practice
List only the hidden entries
From your home directory, list only the entries whose names start with a dot, with their sizes and owners. Exclude
.and..themselves.Check your result
Every line should start with
-ordand every name should start with a dot..bashrcor.profileshould be among them.Hint
A glob such as
.[!.]*skips.and... Add-dso directories are not expanded.Solution
ls -ld ~/.[!.]* - Challenge
Why does this path fail?
Create the sample tree, then work out from which of the four directories the command
cat ../conf/app.confsucceeds. Test all four before you answer, and explain each result in one sentence.mkdir -p ~/lab/app/bin ~/lab/app/conf ~/lab/app/logs echo "port=8080" > ~/lab/app/conf/app.confCheck your result
It works from
binand fromlogs, because..is~/lab/appandconfis a sibling. It fails fromconf(it would look forconf/conf) and fromapp(..is~/lab, which has noconf).Hint
Replace
..with the absolute path it stands for, then ask whether that file exists.Solution
cd ~/lab/app/bin && cat ../conf/app.conf cd ~/lab/app/logs && cat ../conf/app.conf cd ~/lab/app/conf && cat ../conf/app.conf cd ~/lab/app && cat ../conf/app.confport=8080 port=8080 cat: ../conf/app.conf: No such file or directory cat: ../conf/app.conf: No such file or directory