Why the Shell Matters
The command line is the common language of every server, container, and cloud console. Whatever GUI wrapper exists today, the real system is text.
A systems engineer who can’t drive a shell is like a surgeon who can’t use a scalpel. Everything downstream in this curriculum — OS internals, containers, CI/CD, infrastructure-as-code, debugging — happens at the command line first.
What the Shell Is
The shell is a program that reads your commands and tells the kernel to execute them. The most common is bash (or zsh on macOS). You’re typing into a process, and that process:
- expands expressions (
*,~,$VAR), - finds the executable on your
PATH, - launches it as a child process,
- and reports its exit status.
Every command is a child process of the shell — which is exactly the fork/exec machinery you’ll study in the Operating Systems level.
Navigation and the Filesystem
pwd # where am I
ls -la # list with permissions, owner, size
cd ~/projects # home is ~ ; cd - returns to previous dir
find . -name "*.log" # search by name
tree # directory structure (install if missing)
The Unix filesystem is one tree rooted at /. Key mounts you’ll meet constantly:
/etc— config/var/log— logs/tmp— scratch space/proc— live kernel info/dev— devices/homeor/Users— user homes
Permissions and Ownership
Every file has an owner, a group, and a 9-bit mode: rwxr-xr-- = read/write/execute for user, read/execute for group, read for others.
chmod 755 script.sh # rwxr-xr-x (7=rwx, 5=r-x, 4=r--)
chmod +x script.sh # add execute (the common practical form)
chown alice:dev file # change owner:group
umask 022 # default new-file permissions
On a directory, x means searchable (you may traverse it) and w means you may add/remove entries. Executing a file also requires x.
This is your first real taste of kernel-level access control — the same model you’ll see in file-system and security topics.
Pipes and Redirection
The Unix philosophy: small programs that each do one thing, composed with pipes.
command > out.txt # stdout → file (overwrite)
command >> out.txt # stdout → file (append)
command 2> err.log # stderr → file
command < input.txt # stdin ← file
cmd1 | cmd2 # stdout of cmd1 → stdin of cmd2
Every process has three standard streams — stdin (0), stdout (1), stderr (2). Pipes wire one process’s stdout into another’s stdin, and the kernel buffers between them.
That lets you build processing pipelines without intermediate files:
ps aux | grep nginx | awk '{print $2}' | sort -n | head
Text Processing Filters
| Tool | Purpose | Example |
|---|---|---|
grep | filter lines by pattern | grep -ri "error" /var/log/ |
sort / uniq | sort / collapse duplicates | `sort |
head / tail | first / last lines | tail -f app.log (follow) |
wc -l | count lines | grep -c error log |
awk | columnar processing | awk '{print $1, $NF}' |
sed | stream editing | sed 's/foo/bar/g' |
Learn grep and awk to fluency — they are the fast path to answering questions about any log or config from memory.
Environment and PATH
The shell carries an environment — a set of NAME=value variables inherited by every child process:
export EDITOR=vim # child processes inherit
PATH=$PATH:~/bin # where the shell looks for executables
echo $HOME $USER $PWD # read variables
PATH is the directory list the shell searches when you type a bare command name. If a command is “not found,” 90% of the time the binary exists but isn’t on your PATH.
Process Control and Signals
cmd & # run in background
jobs # list background jobs
fg / bg # bring a job to foreground / background
kill -TERM <pid> # send SIGTERM (polite stop)
kill -KILL <pid> # send SIGKILL (uncatchable)
Ctrl+C # SIGINT (interrupt the foreground job)
Signals are the OS’s notification mechanism: SIGTERM asks a process to exit, SIGKILL forces it.
Graceful shutdowns, systemd stop, and container stop all reduce to signals — a concept you’ll meet again in the process-management topic.
Shell Scripting Basics
Scripts are just sequences of commands with variables, conditionals, and loops:
#!/usr/bin/env bash
set -euo pipefail # fail fast: error, unset var, or pipe failure
for f in *.log; do
echo "checking $f"
grep -q "panic" "$f" && echo "$f has a panic"
done
set -euo pipefail is the standard safety header — without it, scripts silently continue after errors. A script’s exit status ($?) is how CI systems, supervisors, and containers decide whether a run succeeded.
Practice Trajectory
- Navigate the whole filesystem with
cd,ls -la, andfind; identify/etc,/var/log,/proc,/devon your machine. - Build a pipeline that reads an access log and prints the top-10 most-visited paths:
awk '{print $7}' | sort | uniq -c | sort -rn | head. - Launch a long command in the background, inspect it with
jobs/ps, then stop it withSIGTERM. - Write a 10-line script with
set -euo pipefailthat checks a directory for files newer than a day and lists them. - Add two aliases and a
PATHentry to your~/.bashrcor~/.zshrc; explain why environment changes need a new shell (orsource).
When It’s the Right Tool
| Situation | Takeaway |
|---|---|
| Any server or container | The shell is the primary interface |
| Log analysis / debugging | grep + awk + tail -f answer most questions |
| Automation | A script is the smallest unit of infrastructure-as-code |
| CI/CD | Pipelines are shell scripts with a runner |
| Interview / day-to-day | Shell fluency is a baseline expectation, not a bonus |