The Shell and the Filesystem
Move around a Linux machine, read and edit files, and stop fearing the terminal.
By the end of this session you will be able to:
- State exactly where you are in a Linux filesystem and move anywhere else in it using both absolute and relative paths
- Read any text file on the machine and pull one line out of a large one, without opening an editor
- Edit a file you own and a file you do not, and read the permission bits that decide which is which
Everything else in this course runs on a Linux machine. Docker builds on it, Kubernetes schedules onto it, your cloud instance boots it. If you cannot answer "where am I and what is in this directory" without guessing, every later error message will look like magic.
Use Ubuntu 26.04 LTS as your reference machine. A virtual machine, WSL on Windows, or a cheap VPS all behave the same for this session.
Where you are is a real thing
The shell prints a prompt and waits. Every command you type runs relative to one directory, your current working directory, and the single most common beginner failure is running a correct command in the wrong place. So ask first:
pwdThat prints something like /home/student. Now look around:
ls
ls -l
ls -laPlain ls gives you names. -l gives the long form: permissions, owner, group, size in bytes, modification time. -a adds entries starting with a dot, which the shell hides by default. Configuration lives in those dotfiles, so ls -la is the version you actually want on a server.
Moving is cd, and it takes two kinds of path. An absolute path starts with / and means the same thing from anywhere. A relative path does not, and means "from here":
cd /etc
pwd
cd ..
pwd
cd ~
cd -.. is the parent directory, . is the current one, ~ is your home directory, and cd - jumps back to where you just were. cd with no argument goes home.
Now the habit that saves you the most time: press Tab. Type cd /et, hit Tab, and the shell completes it. Hit Tab twice on an ambiguous prefix and it lists the candidates. If Tab does not complete, what you are typing does not exist, and you found your typo before running the command instead of after.
One tree, starting at /
Windows gives you C: and D: as separate roots. Linux has exactly one root, /, and everything hangs off it, including extra disks, which get attached at some directory inside the tree. There is no second tree to get lost in.
Six directories carry most of what you care about:
/etcis configuration, almost all of it plain text you can read/varis data that changes while the machine runs, including/var/log/home/yournameis your own files, and the only place you can write without asking/usr/binand/usr/local/binhold the programs the shell runs/tmpis scratch space that gets cleared/optis where hand-installed third party software tends to land
That last one matters in two sessions, when you install an app by hand and write down where its files went.
The shell finds programs by searching a list of directories in order. Print that list, then find where one program actually lives:
echo $PATH
command -v ssh"Command not found" rarely means the program is missing. It usually means the program is not in one of those directories.
Reading a file is not editing it
Opening an editor to read a file is how files get changed by accident. Read them with tools that cannot write.
cat /etc/os-releasecat dumps the whole file to your screen, which is right for short files:
PRETTY_NAME="Ubuntu 26.04 LTS"
NAME="Ubuntu"
VERSION_ID="26.04"
VERSION="26.04 LTS (Resolute Raccoon)"
ID=ubuntuFor anything long, use less, which pages instead of flooding your terminal:
less /etc/servicesInside less: Space moves down a page, b moves back, / searches, n jumps to the next match, and q quits. Learn q now. Being stuck in a pager with no visible way out is a common reason people give up on the terminal.
When you only want the top or the bottom:
head -n 5 /etc/passwd
tail -n 5 /etc/passwdAnd when you want one line out of thousands, or one line out of a whole directory tree, use grep:
grep -n "^root" /etc/passwd
grep -rn "$USER" /etc 2>/dev/null-n prints line numbers, -r searches recursively, and -i ignores case. The 2>/dev/null throws away the permission errors from files you are not allowed to read, so the real matches are not buried. That is the difference between "the config is somewhere in /etc" and knowing the file and the line number.
Editing, and the bit that says no
Look at the long listing again and read it properly:
-rw-r--r-- 1 root root 221 Apr 23 09:12 /etc/hostsThe first character is the type: - for a regular file, d for a directory, l for a symbolic link. The next nine are three groups of three: what the owner can do, what the group can do, and what everyone else can do, each as read, write, execute. So rw-r--r-- owned by root means root changes it and you only read it.
That is why editing your own file just works:
nano ~/notes.txtIn nano, ^O in the help bar means Ctrl and O. Ctrl+O then Enter saves, Ctrl+X exits. Editing a root-owned file needs sudo:
sudo nano /etc/hostssudo runs one command as the administrator. It is not a general fix for a command that failed: if the reason was a wrong path or a typo, sudo just fails as root.
The execute bit is the one people trip over. Make a script and watch it:
printf '#!/bin/bash\necho hello from a script\n' > ~/hello.sh
bash ~/hello.sh
~/hello.sh
chmod u+x ~/hello.sh
~/hello.shbash ~/hello.sh works immediately, because you are running bash and handing it a file to read. ~/hello.sh fails until chmod u+x adds execute permission for the owner, because then you are asking the kernel to run the file itself.
Try it
On your Linux machine, starting from your home directory:
mkdir -p ~/webcraft/notes
cd ~/webcraft/notes
cp /etc/os-release distro.txt
grep -n "VERSION=" distro.txtThen run nano notes.md and write three lines: the version string you just grepped, the absolute path of the directory you are in, and one command from this session you had to look up. Save with Ctrl+O and Enter, exit with Ctrl+X.
Success condition: from any directory on the machine, ls -l ~/webcraft/notes lists both distro.txt and notes.md with your username in the owner column, and cat ~/webcraft/notes/notes.md prints your three lines. If you needed sudo at any point, you were writing in the wrong directory.
Common mistakes
- Typing paths by hand instead of pressing Tab. Half of all "no such file or directory" errors are typos in a path Tab would have completed correctly, and Tab confirms the thing exists before you commit.
- Reaching for sudo the moment a command fails. Read the error first. "Permission denied" is a job for
sudo. "No such file or directory" is a job forpwdandls, and running it as root changes nothing except the damage a typo can do. - Using
caton a large file. It scrolls past faster than you can read and pushes everything useful out of your scrollback. Uselessto browse,headortailfor the ends,grepwhen you know what you are looking for. - Copying unusual flags off a blog post. Ubuntu has been replacing the classic GNU versions of these commands with a Rust reimplementation, starting in 25.10, and obscure flags are exactly where two implementations differ. The standard flags here work on either. When unsure,
man lson the machine in front of you beats a search result.
Where this goes next
The next session, Processes, Ports, and Logs, turns the same skills on a running machine: which programs are actually running, which port each one listens on, and what it wrote into a file under /var/log. You already know how to find and read that file, which is most of the work.