Lesson 04

The Command
Line

The terminal is where you talk to Linux directly. Not as intimidating as it looks — once you know these commands, you can handle 80% of what you'll ever need to do in a terminal.

7 categories
~20 min read
Practice as you go

Before You Type

Reading the prompt.

When you open a terminal, you see a prompt. It tells you who you are, where you are, and whether you have elevated privileges. Learn to read it before you start typing.

mike@machine:~/projects/linux-101$ _
mike ← your username
machine ← hostname (computer name)
~/projects/linux-101 ← current directory (~ = your home folder)
$ ← regular user (type carefully)
# ← root / sudo (type very carefully)
josh@machine: ~
josh@machine:~$ uname -a
Linux machine 6.1.0-26-amd64 #1 SMP x86_64 GNU/Linux
josh@machine:~$

↑ Click any command card below to run it here

Tab completion is your best friend. Start typing a command or file name and press Tab — the shell completes it, or shows you the options. It saves enormous amounts of typing and prevents typos. Press Ctrl+R to search your command history interactively.

Category 01

Navigation

The filesystem is a tree. You're always "in" one directory. These commands move you around and show you what's there.

No commands match — try a different term.

pwd
Print Working Directory. Shows exactly where you are in the filesystem right now.
$ pwd /home/mike/projects/linux-101
ls
List — list files in the current directory. Use ls -la to see hidden files and file sizes in detail.
$ ls -la drwxr-xr-x mike 4096 . drwxr-xr-x mike 4096 .. -rw-r--r-- mike 8192 index.html -rw-r--r-- mike 512 style.css
cd
Change Directory. Use cd ~ to return home, cd .. to go up one level, cd - to return to previous directory.
$ cd ~/projects # absolute path $ cd linux-101 # relative path $ cd .. # go up one level $ cd - # go back
mkdir
Make a new directory. Use mkdir -p to create nested directories all at once.
$ mkdir my-project $ mkdir -p a/b/c # creates a, b, and c
history / !!
Show every command you've typed. !! re-runs the last command — most useful when you forget to add sudo. ! followed by a number runs that history entry. Ctrl+R searches history interactively as you type.
$ history 498 apt update 499 sudo apt update 500 ls -la $ !! # re-run last command $ sudo !! # re-run last command with sudo $ !499 # run entry 499 by number $ history | grep ssh # find a past command Ctrl+R # interactive reverse search

Path shortcuts: ~ = your home directory (/home/username). . = current directory. .. = parent directory. / alone = the root of the entire filesystem.

Category 02

Files

Most of what you do in a terminal involves reading, copying, moving, or deleting files. These are the core tools.

cat
Concatenate — originally designed to join multiple files together and print the result. Most people use it to print a single file to the terminal, which works fine. Short files only — use less for anything longer than a screen.
$ cat /etc/os-release $ cat ~/.bashrc
less
Scrollable file viewer. Press q to quit, /word to search, n for next match. Better than cat for any file over ~50 lines.
$ less /var/log/syslog # q = quit # / = search # G = end of file # g = top of file
head / tail
Show the first or last N lines of a file. tail -f follows a file as it grows in real time — useful for watching logs.
$ head -20 README.md # first 20 lines $ tail -50 error.log # last 50 lines $ tail -f /var/log/syslog # follow live
cp
Copy a file or directory. Use cp -r to copy directories and their contents recursively.
$ cp file.txt backup.txt $ cp -r mydir/ backup/
mv
Move or rename a file. Moving within the same drive is instant (just changes the name in the directory table). Renaming is the same operation.
$ mv old-name.txt new-name.txt # rename $ mv file.txt ~/Documents/ # move
rm
Remove (delete) files. Permanent — there is no Trash. Use rm -r for directories. Be deliberate.
$ rm file.txt $ rm -r old-directory/
⚠ No undo. No recycle bin. Think first.
touch
Create an empty file, or update the timestamp of an existing file.
$ touch newfile.txt $ touch -m existingfile.txt # update timestamp
tar
Tape Archive — creates and extracts compressed archives. The flags look cryptic until you break them down: x=extract, c=create, z=gzip, f=filename follows. Keep f last. The v flag prints each file as it's processed.
$ tar xzf archive.tar.gz # extract here $ tar xzf archive.tar.gz -C /dest # extract to a dir $ tar czf backup.tar.gz mydir/ # create archive $ tar tzf archive.tar.gz # list contents, don't extract $ tar xzvf archive.tar.gz # extract + print filenames
nano
Simple terminal text editor — the approachable one. When you need to edit a config file and don't want to deal with modal editing, reach for nano. Controls are shown at the bottom of the screen. ^ means Ctrl.
$ nano ~/.bashrc $ sudo nano /etc/hosts # Controls (shown at the bottom): # Ctrl+O → save (write Out) # Ctrl+X → exit # Ctrl+W → search # Ctrl+K → cut line # Ctrl+U → paste

Category 03

Search, Text & Pipes

This is where the Unix philosophy pays off. Small tools, connected by pipes, compose into powerful one-liners.

grep
Search for a pattern in files or in piped text. One of the most-used commands in the terminal.
$ grep "error" /var/log/syslog $ grep -r "TODO" ~/projects/ # recursive $ grep -i "kernel" dmesg.txt # case-insensitive $ grep -n "import" main.py # show line numbers
find
Find files by name, type, size, date, or any combination. More powerful than it looks.
$ find . -name "*.log" $ find /etc -name "*.conf" -type f $ find ~ -mtime -7 # modified in last 7 days $ find . -size +100M # larger than 100MB
| (pipe)
Send the output of one command as input to the next. The backbone of the Unix philosophy in action.
$ cat /etc/passwd | grep mike $ ls -la | grep ".conf" $ ps aux | grep firefox | wc -l # "how many firefox processes are running?"
> and >>
Redirect output to a file. > overwrites; >> appends. 2> redirects errors. &> redirects both stdout and stderr.
$ echo "hello" > file.txt # create/overwrite $ echo "world" >> file.txt # append $ some-command 2> errors.log # capture errors $ cmd &> all-output.log # capture everything
wc
Word count — counts lines, words, and characters. Most useful with -l for line counts, especially in pipes.
$ wc -l /etc/passwd # how many users? $ ls ~/projects | wc -l # how many projects? $ cat file.txt | wc -w # word count
sort / uniq
sort sorts input lines. uniq removes consecutive duplicates (so sort first). Often used together in pipes to count unique occurrences.
$ cat file.txt | sort $ cat file.txt | sort | uniq $ cat file.txt | sort | uniq -c # count each $ cat file.txt | sort | uniq -c | sort -rn # rank
echo
Print text to the terminal. More useful than it sounds — the fastest way to check what an environment variable is set to, and standard practice for debugging scripts and one-liners.
$ echo "hello world" $ echo $PATH # print an environment variable $ echo $USER # your username $ echo $HOME # your home directory $ echo $? # exit code of last command (0 = success) $ echo "text" >> ~/.bashrc # append a line to a file

Category 04

Permissions

Every file and directory on a Linux system has an owner and a set of permissions that control who can read it, write to it, and execute it. Understanding this unlocks the security model.

Read the permission string from ls -l:

-rwxr-xr-x 1 mike users 4096 Jun 22 script.sh ─────────└── owner rwx = read, write, execute │ └── group r-x = read, no write, execute │ └── others r-x = read, no write, execute │└── file type: - = regular file, d = directory, l = symlink
chmod
Change file permissions. Use numeric mode (755, 644) or symbolic mode (u+x, go-w). Numeric is faster once you know the values.
$ chmod +x script.sh # make executable $ chmod 755 script.sh # rwxr-xr-x $ chmod 644 config.txt # rw-r--r-- (typical file) $ chmod 600 secret.key # rw------- (private!)
sudo
Switch User, Do — not "superuser do." Runs one command as another user (root by default). Uses your password, not root's. Logs every command. Safer than a root shell because each command is explicit and auditable.
$ sudo apt update $ sudo systemctl restart nginx $ sudo -u www-data ls /var/www # run as a different user $ sudo -i # enter root shell (use sparingly) $ whoami # confirm who you are
Only use sudo for commands that actually need it. It uses your password, but it's running as root.
su
Switch User — starts a shell as a different user. su - becomes root (needs the root password). su - username becomes any user. The dash matters: it loads that user's full environment, not just their identity.
$ su - # become root (enter root's password) $ su - mike # become mike (enter mike's password) $ su -c "apt update" - # run one command as root, then exit $ exit # return to your original user
If you left the root password blank during Debian install, su - won't work — use sudo -i instead.
chown
Change the owner (and optionally the group) of a file. Usually requires sudo. Most common when moving files between users or setting up service directories.
$ sudo chown mike file.txt $ sudo chown mike:users file.txt $ sudo chown -R mike ~/mydir/ # recursive
Numeric permissions
Each permission (r/w/x) has a value: read=4, write=2, execute=1. Add them for each group: owner, group, others.
7 = rwx (4+2+1) = full 6 = rw- (4+2) = read/write 5 = r-x (4+1) = read/execute 4 = r-- (4) = read only 0 = --- (0) = no permissions 755 → owner=rwx, group=rx, others=rx 644 → owner=rw, group=r, others=r 600 → owner=rw, nobody else

Category 05

Processes & System

Every running program is a process. Linux gives you full visibility and control over all of them — yours and the system's. This section also covers disk space, RAM, and service management, since you'll reach for all of these together.

ps
Show running processes. ps aux is the classic — shows all processes from all users with CPU and memory usage.
$ ps aux USER PID %CPU %MEM COMMAND mike 1234 0.1 1.2 firefox mike 2345 0.0 0.3 bash $ ps aux | grep firefox # find a process
top / htop
Live process monitor. top is universal — every Linux system has it. htop is friendlier and supports mouse input. Install htop; use it daily.
$ top # built-in, always available $ htop # install separately, much nicer # In htop: # F6 = sort by column # F9 = kill process # F2 = settings # q = quit
kill / killall
Stop a process. kill PID sends a gentle stop signal. kill -9 PID is the hard kill — process cannot refuse it. killall name kills by process name.
$ kill 1234 # polite stop (SIGTERM) $ kill -9 1234 # hard kill (SIGKILL) $ killall firefox # kill all firefox procs
Try SIGTERM first. Use -9 only when the process won't stop.
Ctrl+C / Ctrl+Z
Keyboard shortcuts for process control. Ctrl+C interrupts (kills) a foreground process. Ctrl+Z suspends it; bring it back with fg.
Ctrl+C → kill foreground process Ctrl+Z → suspend (pause) it $ fg → resume in foreground $ bg → resume in background $ jobs → list background jobs
systemctl
Control system services managed by systemd. Start, stop, restart, enable at boot, or check status. Most software you install that runs in the background — servers, Bluetooth, networking — is a systemd service.
$ systemctl status bluetooth $ sudo systemctl start nginx $ sudo systemctl stop nginx $ sudo systemctl restart nginx $ sudo systemctl enable nginx # start on boot $ sudo systemctl disable nginx # don't start on boot $ systemctl list-units --type=service --state=running
df / du
Disk Free and Disk Usage — two different questions. df -h shows how full each mounted filesystem is. du -sh * shows how much space each item in the current directory uses. When your disk fills up, run both.
$ df -h # how full are my filesystems? $ du -sh * # what's taking space here? $ du -sh ~/Downloads # size of a specific dir $ du -sh * | sort -h # sort by size, largest last
free -h
Show RAM and swap usage. The column to watch is available — not free. Linux deliberately uses spare RAM for disk cache, which is reclaimed instantly when needed. A small free value is normal and healthy.
$ free -h total used free available Mem: 15Gi 6.2Gi 400Mi 8.0Gi Swap: 2Gi 0Mi 2Gi # available = free + cache Linux can reclaim # "used" RAM includes cache — don't panic

Everything is a file — even processes. Each process gets a directory under /proc/<PID>/ containing its memory maps, file descriptors, environment variables, and more. You can inspect a running process without any special tools, just cat and ls. Try: ls /proc/self/

/dev is a directory of virtual device files. Your kernel's random number generator is readable like a file:

tr -dc '[:digit:]' < /dev/urandom | head -c 10

This reads raw random bytes from /dev/urandom, pipes them through tr to keep only digits, and takes the first 10 characters. /dev/urandom is not a file on your disk — it's an interface to the kernel's entropy pool, presented as a file. Same idea as /dev/sda (your hard drive), /dev/null (a discard sink), and /dev/zero (infinite zeros). One interface — read/write — for everything.

Category 06

Getting Help

Every command on Linux comes with documentation built in. You never need to Google basic syntax — the answer is already on your machine.

man
The manual. Comprehensive documentation for almost every command. Press q to quit, / to search within the page.
$ man ls $ man chmod $ man man # meta # Sections: # 1 = user commands (most common) # 5 = file formats # 8 = system administration
--help
Quick usage summary. Most commands support it. Faster than man when you just need to remember which flag does what.
$ ls --help $ grep --help $ chmod --help # Also works with -h on many commands: $ curl -h
tldr
Community-maintained practical examples. Install with your package manager. Shows the commands you actually use — not the complete reference like man.
$ sudo apt install tldr # install it $ tldr ls $ tldr tar # tar is notoriously complex $ tldr git commit
which / whereis
Find where a command is installed. Useful when a command behaves unexpectedly or when you have multiple versions installed.
$ which python /usr/bin/python3 $ which python3 pip node # shows path for each $ whereis nginx # binary, source, and man pages

The most useful habit you can build: when a command does something unexpected, run it again with --help or man before Googling. The documentation is better than most Stack Overflow answers, it's version-accurate for your system, and it builds a mental model that transfers to every other command.

Category 07

Networking

You don't need to know much networking to use Linux productively — but these three commands will get you out of most trouble and let you work with remote machines.

ping
Test whether a host is reachable and how long packets take to arrive. First thing to run when the network seems broken. On Linux it runs forever by default — use Ctrl+C to stop, or -c 4 for exactly 4 packets.
$ ping google.com # Ctrl+C to stop $ ping -c 4 google.com # send exactly 4 packets $ ping 192.168.1.1 # test your router $ ping 8.8.8.8 # test internet (Google DNS)
curl
Transfer data from URLs. Most commonly used to download files, fetch a web page, or test whether an endpoint is responding. Installed on nearly every Linux system. Use wget as an alternative for simple downloads.
$ curl https://example.com # print to terminal $ curl -O https://example.com/file.zip # download file $ curl -I https://example.com # headers only $ curl -s https://api.example.com/data # silent (no progress bar) $ curl -L https://example.com # follow redirects
ssh
Open an encrypted shell on a remote machine. Once you have more than one machine, this becomes essential. The long form gets tedious fast — set up ~/.ssh/config to replace it with a short alias.
$ ssh user@192.168.1.100 $ ssh user@host -p 2222 # non-standard port $ ssh -i ~/.ssh/mykey user@host # specific key $ ssh homeserver # after ~/.ssh/config setup
Appendix D: Dotfiles covers ~/.ssh/config — define host aliases so you never type the full address again.

Quick Reference

The essential 31.

Command What it does Category
pwdShow current directoryNavigation
ls -laList files with detailsNavigation
cd <path>Change directoryNavigation
mkdir <name>Create a directoryNavigation
history / !!Command history / re-run last commandNavigation
cat <file>Print file contentsFiles
less <file>Scroll through a fileFiles
tail -f <file>Follow a file as it growsFiles
cp / mv / rmCopy / move / delete filesFiles
tar xzf <file>Extract a .tar.gz archiveFiles
nano <file>Edit a file in the terminalFiles
grep <pattern>Search text or filesSearch
find . -nameFind files by nameSearch
cmd1 | cmd2Pipe output between commandsSearch
cmd > fileRedirect output to fileSearch
echo $VARPrint text or variable valueSearch
chmod 755Set file permissionsPermissions
sudo <cmd>Switch User, Do — run one command as rootPermissions
su -Switch User — open a root shellPermissions
ps auxList all processesProcesses
htopLive process monitorProcesses
kill / killallStop a processProcesses
Ctrl+CKill foreground processProcesses
systemctl statusCheck / start / stop a serviceProcesses
df -h / du -shDisk free / disk usageProcesses
free -hRAM usage (watch "available")Processes
man <cmd>Full manual pageHelp
tldr <cmd>Quick practical examplesHelp
ping <host>Test host reachabilityNetworking
curl -O <url>Download a file from a URLNetworking
ssh user@hostConnect to a remote machineNetworking