Lesson 0.1 · The Shell
The graphical desktop is a convenience layer painted on top of something older and more powerful. Underneath every server, container, and cloud instance you will ever manage is a shell — a text program that reads commands and runs them. DevOps and security work happens here, because servers usually have no screen at all. This lesson makes the shell feel like home.
What a shell actually is
Section titled “What a shell actually is”When you open a terminal, a program starts running inside it called a shell. The most common is bash; macOS ships zsh (which is bash-compatible for everything here). The shell’s job is a loop:
- Print a prompt (often ending in
$). - Wait for you to type a command and press Enter.
- Find the program you named, run it with the arguments you gave, show its output.
- Go back to step 1.
That’s it. Everything else is detail. A command line like this:
ls -l /etcmeans: run the program ls, pass it the option -l (long format) and the argument
/etc (which directory to list). The shell finds the ls program, starts it, and shows you
what it prints.
Where am I? Navigating the filesystem
Section titled “Where am I? Navigating the filesystem”A Unix filesystem is a single tree starting at / (the root). Everything — every disk,
every file — hangs off that one root. There are no C: or D: drives.
pwd # "print working directory" — where am I right now?ls # list files in the current directoryls -l # long format: permissions, owner, size, datels -la # also show hidden files (names starting with .)cd /etc # change directory to /etc (absolute path — starts at /)cd nginx # change into ./nginx (relative path — starts from here)cd .. # go up one level to the parent directorycd ~ # go to your home directory (~ is shorthand for it)cd - # go back to the previous directory you were incd # with no argument, also goes homeAbsolute vs. relative paths is the single most common beginner confusion:
- An absolute path starts with
/and is understood from the root:/etc/nginx/nginx.conf. It means the same thing no matter where you are. - A relative path is understood from your current directory:
nginx/nginx.confmeans “starting from where I am now.” .means “here”,..means “the parent directory”,~means “my home directory”.
Special locations worth memorizing:
| Path | What it is |
|---|---|
/ |
The root of everything |
~ or /home/you |
Your home directory |
/etc |
System configuration files |
/var/log |
Log files |
/tmp |
Temporary files (wiped on reboot) |
/usr/bin, /bin |
Installed programs |
Looking at files
Section titled “Looking at files”cat file.txt # dump the whole file to the screenless file.txt # page through a file (q to quit, / to search)head file.txt # first 10 lineshead -n 20 file.txt # first 20 linestail file.txt # last 10 linestail -f app.log # follow a log file live as it grows — you'll use this constantlywc -l file.txt # count linesfile mystery # guess what kind of file something isstat file.txt # detailed metadata: size, timestamps, permissionstail -f is worth calling out: it keeps running and prints new lines as they’re appended.
When you’re watching a server do something, this is how you see it happen in real time.
Press Ctrl-C to stop it.
Creating, copying, moving, deleting
Section titled “Creating, copying, moving, deleting”mkdir project # make a directorymkdir -p a/b/c # make nested directories, creating parents as neededtouch notes.txt # create an empty file (or update its timestamp)cp source.txt dest.txt # copy a filecp -r dir1 dir2 # copy a directory and everything in it (-r = recursive)mv old.txt new.txt # rename (move) a filemv file.txt ~/archive/ # move a file into another directoryrm file.txt # delete a filerm -r directory # delete a directory and its contentsrmdir empty-dir # delete an empty directoryGlobbing: matching many files at once
Section titled “Globbing: matching many files at once”The shell expands wildcards into lists of matching filenames before the command runs:
ls *.txt # everything ending in .txtls log-2026-*.txt # everything matching that patternls report-?.pdf # ? matches exactly one character: report-1.pdf, report-a.pdfls {jpg,png} # brace expansion: expands to jpg pngcp *.conf backup/ # copy every .conf file into backup/* matches any number of characters, ? matches exactly one. This is globbing, done by
the shell — the program you’re running never sees the *, only the final list of names.
Permissions: who can do what
Section titled “Permissions: who can do what”Every file has an owner, a group, and a set of permissions for three classes of
user: the owner, the group, and everyone else (“others”). Run ls -l and you’ll see them:
-rwxr-xr-- 1 alice devs 4096 Jul 20 09:00 deploy.shRead the permission block -rwxr-xr-- in four parts:
- First character:
-a regular file,da directory,la symbolic link. - Next three (
rwx): what the owner (alice) can do — read, write, execute. - Next three (
r-x): what the group (devs) can do — read and execute, not write. - Last three (
r--): what others can do — read only.
Changing them:
chmod +x script.sh # add execute permission (make a script runnable)chmod -x script.sh # remove execute permissionchmod 644 file.txt # owner read/write, group + others read (common for files)chmod 600 secret.key # owner read/write only — nobody else (use for keys!)chmod 755 script.sh # owner all, group + others read/execute (common for scripts)chown alice file.txt # change the owner (usually needs sudo)chown alice:devs file.txt # change owner and groupThe numbers are octal: read=4, write=2, execute=1, added together. So 7 = rwx,
6 = rw-, 5 = r-x, 4 = r–. chmod 640 means owner rw-, group r–, others nothing.
You’ll internalize 600 (private key), 644 (normal file), and 755 (script/directory)
fast because you’ll type them constantly.
sudo and root
Section titled “sudo and root”root is the all-powerful administrator account (user ID 0). You rarely log in as root
directly. Instead you run individual commands as root with sudo:
sudo apt update # run this one command as rootsudo systemctl restart nginxThe golden rule you’ll hear again in Module 2: use the least privilege that gets the job done. Don’t run everything as root “to avoid permission errors” — those errors are often the system correctly stopping you from a mistake.
Pipes and redirection: composing small tools
Section titled “Pipes and redirection: composing small tools”This is the idea that makes the Unix shell powerful. Each tool does one thing. You connect
them. The pipe | takes the output of one command and feeds it as the input of the next:
cat access.log | grep "404" | wc -l # count lines containing "404"Read left to right: dump the log, keep only lines with “404”, count them. Three simple tools became a “count of 404 errors” tool, and you invented it on the spot.
Redirection sends output to (or reads input from) files instead of the screen:
echo "hello" > file.txt # write output to a file (OVERWRITES it)echo "world" >> file.txt # append output to a file (adds to the end)command < input.txt # feed a file in as the command's inputcommand 2> errors.txt # redirect error messages (stderr) to a filecommand > out.txt 2>&1 # send both normal output and errors to one filecommand 2>/dev/null # throw errors away (/dev/null is the void)There are three streams every program has: stdin (input, 0), stdout (normal
output, 1), and stderr (error output, 2). Pipes and > handle stdout by default; 2>
handles stderr. Understanding these three is what lets you control exactly where output goes.
The essential text-processing tools
Section titled “The essential text-processing tools”You will use these five constantly. Learn them now:
grep "pattern" file # print lines matching a patterngrep -r "TODO" . # search recursively through a directorygrep -i "error" log # case-insensitivegrep -v "debug" log # invert: lines that DON'T matchgrep -c "404" access.log # count matching lines
find . -name "*.conf" # find files by name under the current directoryfind /var -type f -size +100M # files over 100MB under /varfind . -name "*.tmp" -delete # find and delete (careful!)
sort file.txt # sort lines alphabeticallysort -n numbers.txt # sort numericallysort -rn numbers.txt # reverse numeric (biggest first)
uniq # collapse adjacent duplicate lines (sort first!)sort file | uniq -c # count occurrences of each unique line
cut -d: -f1 /etc/passwd # cut column 1, using : as the delimiterawk '{print $1}' access.log # print the first whitespace-separated fieldCombined, these solve a huge range of real problems. The classic “top 10 IP addresses in a log” one-liner (which is Lab 2) is nothing but these tools piped together:
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -n 10Read it: extract the first field (the IP) from each line → sort so identical IPs sit together → count each unique IP → sort those counts biggest-first → take the top 10.
Processes: what’s actually running
Section titled “Processes: what’s actually running”A running program is a process with a numeric PID (process ID). Managing processes is daily work on a server.
ps aux # list all running processesps aux | grep nginx # find a specific processtop # live, updating view of processes (q to quit)htop # a nicer top, if installed (you'll install it in Module 2)Every process can receive signals. The two you’ll use:
kill 1234 # politely ask process 1234 to stop (sends SIGTERM)kill -9 1234 # force-kill (SIGKILL) — last resort, no cleanuppkill nginx # kill processes by nameForeground vs. background jobs in your own shell:
long-command # runs in the foreground; your prompt is blockedlong-command & # run it in the background; prompt returns immediatelyCtrl-Z # suspend the foreground jobbg # resume the suspended job in the backgroundfg # bring a background job back to the foregroundjobs # list jobs running in this shellNote this is shell job control — it dies when you close the terminal. For work that must survive a disconnect, you’ll use tmux in the next lesson.
The environment: variables and $PATH
Section titled “The environment: variables and $PATH”The shell keeps a set of environment variables — named values that programs can read:
echo $HOME # print the value of the HOME variableecho $USER # your usernameecho $PATH # the list of directories the shell searches for commandsexport EDITOR=vim # set a variable and make it visible to programs you runenv # list all environment variables$PATH deserves special attention. When you type ls, how does the shell find the ls
program? It looks through each directory listed in $PATH, in order, until it finds one
named ls. That’s why which ls tells you which file will actually run:
which python3 # show the full path of the program that would runtype cd # tell you if something is a program, builtin, or aliasDotfiles: making the shell yours
Section titled “Dotfiles: making the shell yours”When your shell starts, it reads a configuration file in your home directory — ~/.bashrc
for bash, ~/.zshrc for zsh. These are called dotfiles because their names start with a
dot (which makes them hidden). They’re just shell scripts that run at startup. You put your
customizations there:
# Inside ~/.bashrc or ~/.zshrc
# Aliases: short names for longer commandsalias ll='ls -la'alias gs='git status'alias ..='cd ..'
# Environment variablesexport EDITOR=vim
# A cleaner, informative prompt (bash example)export PS1='\u@\h:\w\$ 'After editing, either open a new terminal or reload the file:
source ~/.bashrc # re-run the config in your current shellGetting help without leaving the terminal
Section titled “Getting help without leaving the terminal”man ls # the manual page for ls (q to quit, / to search)ls --help # most tools print a quick help summarytldr tar # community "just show me examples" pages (if installed)Learning to read a man page is a real skill. The SYNOPSIS section shows the grammar of
the command; the OPTIONS section explains each flag. It’s dense, but it’s authoritative
and always available — even on a server with no internet.
Common mistakes to avoid
Section titled “Common mistakes to avoid”- Spaces in commands matter.
rm - rfis notrm -rf. Type carefully. - The shell is case-sensitive.
File.txtandfile.txtare different files. >overwrites without asking. Use>>when you mean to append.- Tab completion is your friend. Start typing a filename and press Tab — the shell finishes it. This prevents typos and is faster. Use it constantly.
- Up-arrow recalls previous commands.
Ctrl-Rsearches your command history. You rarely need to retype anything.
Quick self-check
Section titled “Quick self-check”Before moving on, make sure you can answer these without looking:
- What’s the difference between an absolute and a relative path?
- What does
chmod 600 id_ed25519do, and why would you do it to a key? - What does
cat access.log | grep 500 | wc -lproduce? - What’s the difference between
>and>>? - How do you find which directories the shell searches to run a command?
- Where do your shell customizations live, and how do you reload them?
If any of those are shaky, that’s fine — Lab 2 will drill the pipe-and-filter skills until they’re reflex.