TAI BUI
Back to curriculum
Learn—

The Command Line and Linux

Most AI compute lives on a Linux box you reach over SSH. There's no Finder, no Explorer, no GUI, just a prompt. Get fast here or spend your rented GPU hours googling how to unzip a file.

TIME: ~65 minutesPREREQUISITES: Phase 0, Lesson 01

Learning Objectives

  • Navigate the Linux file system, manage permissions with `chmod`/`chown`, and install packages with `apt` to get a fresh GPU box ready for work
  • Use piping, redirects, and `grep`/`awk` to filter and process training logs from the command line
  • Create persistent tmux sessions with multiple panes for concurrent training and GPU monitoring with `htop`, `nvtop`, and `nvidia-smi`
  • Transfer files and connect to remote GPU boxes with SSH, `scp`, and `rsync`, and recognize the macOS/Windows quirks that trip people up on Linux

The Problem

You develop on macOS or Windows. The moment you SSH into a cloud GPU box, whether that's Lambda, RunPod, Vast.ai, or an EC2 instance, you land in Ubuntu, and the terminal is your only interface. No Finder, no Explorer, no GUI.

You'll also spend more time in that terminal than in any editor. Training runs, GPU monitoring, log tailing, remote sessions, environment management: every AI workflow touches the shell. If you can't navigate the file system, install packages, manage processes, and pipe commands together from the command line, you're stuck paying for idle GPU hours while googling "how to unzip a file on Linux."

This is a survival guide, not a history of Unix or a Bash scripting deep-dive. It covers exactly the terminal and Linux skills that show up constantly in AI work. Nothing more.

Warm-up0/3
1. What does a file path like `/home/ana/notes.txt` tell you?Warm-up
Three folder listings side by side. The first, named /, holds bin, etc, home, tmp, usr and var. The second, home, holds ana and ben. The third, ana, holds notes.txt, photos and todo.md.
What each of the three folders contains.
2. On a normal desktop, how does moving a file to the Trash differ from deleting it permanently?Warm-up
A file manager mock: right-click menu on report.docx with Open, Rename, Move to Trash and Delete Permanently, next to a Trash window already holding three older files and an Empty Trash button.
3. You have used pip or npm to add libraries to a project. What is the general job of a package manager?Warm-up
Terminal running pip install requests in a fresh virtual environment: lines collecting requests and four other packages, an Installing collected packages line, and a Successfully installed line naming all five.

The Concept

Everything below is stuff you'll touch on basically every remote box you ever SSH into. Skim it once, then come back to it as reference. This section is denser than most.

Start from zero: a terminal is just a program that reads the text commands you type and runs them. When you open one, it shows a prompt, usually ending in $ or %, which means "waiting for you to type something." The prompt isn't something you type yourself; it's the shell announcing it's ready. You type a command, like ls, then press Enter to run it, and whatever the command produces prints below. That's the entire loop: type, Enter, read the result, repeat.

The Shell You're In

Check which shell you're running:

bash
echo $SHELL

Most systems use bash or zsh. Both work fine. Every command in this lesson works in either. Know these before anything else:

bash
# Move around
cd ~/projects/taibui.dev
pwd
ls -la
 
# History search: the single most useful shortcut you'll learn
# Ctrl+R, then type part of a previous command. Press Ctrl+R again to cycle matches.
 
clear   # or Ctrl+L, clears the terminal
# Ctrl+C cancels a running command
# Ctrl+Z suspends it (resume with fg)

Filesystem Layout

Linux organizes everything under a single root /, the top of one filesystem tree that every file on the system lives inside. There's no C:\ and no /Volumes.

Mermaid diagram

Your home directory is ~, or /home/your-username in full. Almost everything you do happens here.

The 15 Commands That Cover 95% of It

Moving around:

bash
pwd                         # Where am I?
ls                          # What's here?
ls -la                      # What's here, including hidden files, with details?
cd /path/to/dir             # Go there
cd ~                        # Go home
cd ..                       # Go up one level

Files and directories:

bash
mkdir my-project            # Create a directory
mkdir -p a/b/c              # Create nested directories in one shot
 
cp file.txt backup.txt      # Copy a file
cp -r src/ src-backup/      # Copy a directory (recursive)
 
mv old.txt new.txt          # Rename a file
mv file.txt /tmp/           # Move a file
 
rm file.txt                 # Delete a file (no trash, it's gone)
rm -rf my-dir/              # Delete a directory and everything inside

rm -rf is permanent. There is no undo. Double-check the path before hitting enter.

Reading files:

bash
cat file.txt                # Print entire file
head -20 file.txt           # First 20 lines
tail -20 file.txt           # Last 20 lines
tail -f log.txt             # Follow a log file in real time (Ctrl+C to stop)
less file.txt               # Scroll through a file (q to quit)

Searching:

bash
grep "error" training.log           # Find lines containing "error"
grep -r "learning_rate" .           # Search all files in current directory
grep -i "cuda" config.yaml          # Case-insensitive search
 
find . -name "*.py"                 # Find all Python files under current dir
find . -name "*.ckpt" -size +1G     # Find checkpoint files larger than 1GB

Users and sudo

You're usually logged in as a regular user. Some operations need root, short for the root user, Linux's built-in administrator account with unrestricted access. That's a different "root" from the root / directory earlier; same word, unrelated meaning.

bash
whoami                      # What user am I?
sudo command                # Run a single command as root
sudo su                     # Become root (exit to go back, use sparingly)

On cloud GPU instances you're typically the only user and already have sudo access. Don't run everything as root anyway. Use sudo only when something actually needs it. You'll see sudo show up constantly from here on, including in the permissions and package-install commands below, now that you know what it's doing.

Permissions

Every file has an owner and permission bits. You'll hit this the moment a script won't execute or you can't write to a directory.

Unix permissions track three questions for every file: can the owner read, write, or run it; can the group; and can everyone else. Each of those three slots is a small yes/no/yes triple for read, write, and execute, which is why 755 and 644 below are nothing more than those triples written out as numbers.

bash
ls -l train.py
# -rwxr-xr-- 1 user group 2048 Mar 19 10:00 train.py
#  ^^^             owner permissions: read, write, execute
#     ^^^          group permissions: read, execute
#        ^^        everyone else: read only

Common fixes:

bash
chmod +x train.sh           # Make a script executable
chmod 755 deploy.sh         # Owner: full, others: read+execute
chmod 644 config.yaml       # Owner: read+write, others: read only
 
chown user:group file.txt   # Change who owns a file (needs sudo)

When something says "Permission denied," it's almost always this. chmod +x or sudo fixes most cases.

Package Management with apt

Ubuntu uses apt. This is how you install system-level software.

bash
sudo apt update             # Refresh the package list (always do this first)
sudo apt install -y htop    # Install a package (-y skips confirmation)
sudo apt install -y build-essential  # C compiler, make, etc., needed by many Python packages
sudo apt install -y tmux    # Terminal multiplexer, more on this below
 
apt list --installed        # What's installed?
sudo apt remove htop        # Uninstall

The set you'll install on basically every fresh GPU box:

bash
sudo apt update && sudo apt install -y \
    build-essential \
    git \
    curl \
    wget \
    tmux \
    htop \
    unzip \
    python3-venv

Processes and systemd

A process is just a running instance of a program, and each one gets a numeric PID so you can point at exactly the one you want to stop.

bash
ps aux | grep python        # Find running Python processes
kill 12345                  # Gracefully stop process with PID 12345
kill -9 12345               # Force kill (when graceful doesn't work)

systemd manages background services, or daemons: programs like an inference server that keep running behind the scenes even after you log out. You'll touch it if you run inference servers:

bash
sudo systemctl start nginx          # Start a service
sudo systemctl stop nginx           # Stop it
sudo systemctl restart nginx        # Restart it
sudo systemctl status nginx         # Check if it's running
sudo systemctl enable nginx         # Start automatically on boot

Disk Space

GPU boxes often have limited disk space, and models and datasets fill it fast.

bash
df -h                       # Disk usage for all mounted drives
df -h /home                 # Disk usage for /home specifically
 
du -sh *                    # Size of each item in current directory
du -sh ~/.cache             # Size of your cache (pip, Hugging Face models land here)
du -sh /data/checkpoints/   # Check how big your checkpoints are
 
# Find the biggest space hogs
du -h --max-depth=1 / 2>/dev/null | sort -hr | head -20

Common space savers:

bash
pip cache purge                                    # Clear pip cache
sudo apt clean                                      # Clear apt cache
rm -rf checkpoints/epoch_01/ checkpoints/epoch_02/  # Remove old checkpoints

macOS to Linux Gotchas

If you've used a Mac terminal before, here's where Linux will surprise you. If this is your first terminal ever, skim this table or skip it entirely; nothing else in the lesson depends on it.

macOSLinuxNotes
brew installsudo apt installPackage names sometimes differ: brew install htop and sudo apt install htop behave the same, but brew install readline and sudo apt install libreadline-dev do not.
open file.txtxdg-open file.txtMoot on a remote box with no GUI anyway, so use cat or less.
pbcopy / pbpasteNot availablePipe to/from the clipboard doesn't exist over SSH.
~/.zshrc~/.bashrcmacOS defaults to zsh; most Linux servers default to bash.
/opt/homebrew//usr/bin/, /usr/local/bin/Binaries live in different places.
sed -i '' 's/a/b/' filesed -i 's/a/b/' filemacOS sed needs an empty string after -i. Linux doesn't.
Case-insensitive filesystemCase-sensitive filesystemModel.py and model.py are two different files on Linux.
Line endings \nLine endings \nSame, but Windows uses \r\n, which breaks bash scripts. Run dos2unix to fix.

Quick Reference Card

Navigation:     pwd, ls, cd, find
Files:          cp, mv, rm, mkdir, cat, head, tail, less
Search:         grep, find
Permissions:    chmod, chown, sudo
Packages:       apt update, apt install
Processes:      ps, kill, nvidia-smi
Services:       systemctl start/stop/restart/status
Disk:           df -h, du -sh
Network:        curl, wget, scp, rsync, ssh
Sessions:       tmux new/attach/detach
Check: The Concept0/22
1. What does the `$` or `%` at the start of a terminal line mean?Define
Two terminal windows. The bash one shows two commands, ls and pwd, with their output, then a new line with a blinking block cursor after the first symbol. The zsh one shows a line starting with a percent sign and a block cursor.
2. What is the root directory (`/`) in Linux?Define
Terminal: cd /, pwd printing a single slash, ls listing the standard top-level folders including bin, etc, home, root, tmp, usr and var, then cd ~ and pwd printing /home/ana.
3. In the sense used throughout this lesson, what is a shell?Define
Terminal: echo $SHELL prints /bin/bash, then echo hello prints hello, ls /home prints ana and ben, and echo $0 prints bash.
Each line typed is read and run by the program named /bin/bash.
4. What is the purpose of `sudo` before a command?Define
Terminal on a GPU box as user ubuntu: apt install htop fails with a Permission denied lock-file error, and the next prompt has sudo apt install htop typed in but not yet run.
Error text typed in apt's usual format, not captured on this machine.
5. What is apt?Define
Terminal on Ubuntu: apt --version, apt show htop giving package name, version, section and description, and apt list --installed showing the first few installed packages with their versions.
Real output from an Ubuntu 24.04 machine.
6. What does `chmod` change?Define
Terminal showing ls -l for a folder with config.yaml, deploy.sh and train.py, each line with a mode string, owner, group, size and date, followed by the typed command chmod 755 deploy.sh that has not yet been run.
7. What is systemd's job on Linux?Define
Terminal showing systemctl status for a service called serve: loaded and enabled, active (running) for three days, main process 842 running python serve.py --port 8000. A note says nobody is logged in right now.
Status text typed in systemctl's usual format, not captured here. Dates and PID are examples.
8. What is a PID?Define
Terminal: ps output with a header row (USER, PID, %CPU, %MEM, STAT, COMMAND) and two Python processes, python train.py --epochs 100 and python serve.py --port 8000, each with a user, a number, CPU and memory values.
Real ps output, with the grep line itself left out.
9. What does running `sudo apt update` actually do?Explain
Terminal: sudo apt update printing Hit lines for each package archive, Reading package lists, Building dependency tree, and a final line saying how many packages can be upgraded.
Real output from an Ubuntu 24.04 machine.
10. How does the root user relate to the root directory `/`?Explain
Two small terminals. The first runs whoami, which prints root, and echo $HOME, which prints /root, and id. The second runs cd / and pwd, which prints a single slash, then ls -d bin etc home root lists the four names.
11. Why should you double-check the path before running `rm -rf my-dir/`?Explain
Terminal in a working folder that holds my-data and my-dir. find my-dir lists results.csv and a runs folder with epoch_01.pt and epoch_02.pt. The next line has rm -rf my-dir/ typed but not yet run.
12. What is a key difference between macOS and Linux for `sed -i`?Explain
A script fix_lr.sh holding sed -i 's/lr=0.1/lr=0.01/' config.txt, run on an Ubuntu box where config.txt changes from lr=0.1 to lr=0.01, then a note that the same script is copied to a MacBook and run there.
13. `ls -l` shows `-rwxr-xr-- 1 user group 2048 Mar 19 10:00 train.py`. What can everyone who is neither the owner nor in the group do?Apply
Terminal: ls -l train.py prints -rwxr-xr-- 1 user group 2048 Mar 19 10:00 train.py. Below it, the ten-character mode string is split into boxes: the type character, then owner, group and others, three characters each.
14. You get 'Permission denied' when running a shell script you own. What command fixes it?Apply
Terminal: ls -l script.sh shows -rw-r--r-- owned by ana, whoami prints ana, and running ./script.sh prints bash: ./script.sh: Permission denied.
15. Your GPU box is nearly out of disk. Which command tells you how large `~/.cache` is, so you know whether clearing it is worth it?Apply
A disk bar for the GPU box that is nearly full, above a card for the folder ~/.cache described as pip wheels and Hugging Face models, with its size marked as unknown.
16. You ran a long command a while ago and need it again without retyping it. What is the fastest approach?Apply
Terminal: history | tail -n 4 shows the last four history entries (short commands such as ls, du and cd), followed by an empty prompt. A card shows a long command run a while ago, further back in history: python train.py --epochs 100 --lr 1e-4 --data /data/coco --out runs/exp7.
17. `ps aux | grep python` shows a runaway process with PID 12345. What does `kill 12345` do?Apply
Terminal: ps aux | grep python prints the column header and one Python process, python train.py, with PID 12345 and a CPU column near 100 percent.
A runaway process at close to 100 percent CPU.
18. Your code runs on your Mac, but on the Linux GPU box `import Model` fails even though the repo contains `model.py`. What is the likely cause?Analyze
Two terminals. On the MacBook, python train.py prints training. On the Ubuntu GPU box, ls shows model.py and train.py, head -1 train.py shows import Model, and running train.py ends in ModuleNotFoundError: No module named 'Model'.
The same repo, two machines.
19. A bash script written on Windows fails mysteriously on a Linux GPU box. What is the likely cause?Analyze
Terminal on a Linux GPU box: cat run.sh shows a three-line bash script that looks normal, and running ./run.sh prints bash: ./run.sh: cannot execute: required file not found. A note says the script was written in a Windows editor and copied over.
20. `pip install` of a package fails on a fresh Ubuntu box because it must compile C code. Which apt package was missing?Analyze
Terminal on a fresh Ubuntu box: pip install fastsum downloads the source archive, then fails while building the wheel with error: command 'x86_64-linux-gnu-gcc' failed: No such file or directory, and ERROR: Failed building wheel for fastsum.
Failure text typed in pip's usual format, not captured here. fastsum is a made-up package.
21. You deployed a small inference server that must keep running in the background and start again after a reboot. Which approach fits?Design
A timeline for serve.py, a small inference server: the server is started, you log out, the box reboots, and later clients call it, with a question mark on whether the server is up.
22. You get a fresh Ubuntu GPU box and need a compiler, git, tmux and Python venv support. Which first step fits?Design
Terminal on a fresh Ubuntu GPU box: the os-release lines naming Ubuntu 24.04.5 LTS, whoami printing ubuntu, then an empty prompt. A card lists what is needed before the first training run: a C compiler, git, tmux and Python venv support.

Build It

Everything above is the map. This is how you actually work a session end to end: piping data around, keeping training alive after you disconnect, and moving files to and from a box that doesn't have a GUI.

Piping and Redirects

Every command reads from some input and writes to some output. By default that's your keyboard and your screen, but | reroutes one command's output to become the next command's input, letting you chain small tools together instead of writing one big program to do it all. That's how you process logs, filter output, and combine tools, and you'll use it constantly. grep finds the lines you care about; awk then picks out specific fields from those lines, so pairing them turns raw log noise into just the numbers you need.

bash
# Count how many times "loss" appears in a log
cat train.log | grep "loss" | wc -l
 
# Extract just the loss values from training output ($NF means the last field on the line)
grep "loss:" train.log | awk '{print $NF}' > losses.txt
 
# Watch a log file update in real time, filtering for errors
tail -f train.log | grep --line-buffered "ERROR"
 
# Sort experiments by final accuracy
grep "final_accuracy" results/*.log | sort -t= -k2 -n -r
 
# Redirect stdout and stderr to separate files
python train.py > output.log 2> errors.log
 
# Redirect both to the same file
python train.py > train_full.log 2>&1

The redirects you need, memorized:

SymbolWhat it does
>Write stdout to file (overwrite)
>>Append stdout to file
2>Write stderr to file
2>&1Send stderr to the same place as stdout
|Send stdout of one command as stdin to the next

Background Processes, and Why & and nohup Aren't Enough

Training runs take hours. You don't want to keep a terminal open the whole time.

A command running in your terminal is in the foreground: it ties up that terminal until it finishes, and closing the terminal normally kills it too, via a signal called SIGHUP (literally "hangup," the same idea as a phone call ending). Add & to the end of a command and it moves to the background instead, freeing up your terminal, though it still dies with SIGHUP when you disconnect. nohup goes one step further and tells the process to ignore that signal entirely, which is why it survives you logging out. Each background job also gets a number, shown by jobs, and you refer back to it with %, so %1 means "job 1."

bash
# Run in background (output still goes to terminal)
python train.py &
 
# Run in background, immune to hangup (closing the terminal won't kill it)
nohup python train.py > train.log 2>&1 &
 
# Check what's running in background
jobs
ps aux | grep train.py
 
# Bring background job 1 to the foreground
fg %1
 
# Kill background job 1
kill %1
# or find its PID and kill that
kill $(pgrep -f "train.py")

The honest comparison:

MethodSurvives terminal close?Can reattach?
command &NoNo
nohup command &YesNo (check the log file)
tmuxYesYes

For anything longer than a few minutes, use tmux. That's the whole reason the next section exists.

tmux: One Persistent Session, Many Panes

This is the single most useful tool in this lesson. It deserves one clean explanation instead of a handful of scattered tips, so here it is, properly.

tmux gives you a terminal session that lives on the server, independent of your SSH connection. Close your laptop, lose your Wi-Fi, whatever. The session and everything running inside it keeps going. You reconnect and pick up exactly where you left off. Panes are just split-screen views into that same session, so you can watch a training log scroll by in one pane while you run commands in another, without opening a second SSH connection.

bash
# Install
sudo apt install tmux       # Ubuntu
brew install tmux           # macOS
 
# Start a named session
tmux new -s train
 
# Split horizontally
# Ctrl+B then "
 
# Split vertically
# Ctrl+B then %
 
# Navigate between panes
# Ctrl+B then arrow keys
 
# Detach (session keeps running)
# Ctrl+B then d
 
# Reattach
tmux attach -t train
 
# List sessions
tmux ls
 
# Kill a session
tmux kill-session -t train

A typical training session, start to finish:

bash
tmux new -s train
 
# Pane 1: start training
python train.py --epochs 100 --lr 1e-4
 
# Ctrl+B, " to split, then run the GPU monitor
watch -n1 nvidia-smi
 
# Ctrl+B, % to split vertically, tail the logs
tail -f logs/experiment.log
 
# Now detach with Ctrl+B, d
# SSH out, close your laptop, get coffee, come back
tmux attach -t train

Always run long training jobs inside tmux. Always.

Monitoring: htop, nvtop, nvidia-smi

With tmux running, monitoring is just another pane. The three tools cover different layers: htop shows CPU and general process activity, nvtop shows the same thing but for GPU processes, and nvidia-smi is the raw driver-level readout you can also pipe into scripts.

bash
htop                        # Interactive process viewer, better than top (q to quit)
 
nvtop                       # GPU process viewer (install: apt/brew install nvtop)
 
nvidia-smi                  # Quick GPU check without nvtop
watch -n1 nvidia-smi        # Same, refreshed every second
 
# See which processes are using the GPU, in a script-friendly format
nvidia-smi --query-compute-apps=pid,name,used_memory --format=csv

htop keybindings worth knowing:

  • F6 or >: sort by column (sort by memory to find leaks)
  • F5: toggle tree view (see child processes)
  • F9: kill a process
  • /: search for a process name

Connecting to Remote GPU Boxes

When you rent a cloud GPU from a provider like Lambda, RunPod, or Vast.ai, you connect over SSH.

bash
# Basic connection
ssh user@gpu-box-ip
 
# With a specific key
ssh -i ~/.ssh/my_gpu_key user@gpu-box-ip
 
# Copy files to remote
scp model.pt user@gpu-box-ip:~/models/
 
# Copy files from remote
scp user@gpu-box-ip:~/results/metrics.json ./
 
# Sync a whole directory: faster for many files, resumes on failure
rsync -avz ./data/ user@gpu-box-ip:~/data/
 
# Port forward (access remote Jupyter/TensorBoard locally)
ssh -L 8888:localhost:8888 user@gpu-box-ip
# Now open localhost:8888 in your browser

Use rsync over scp for anything large, because it only transfers changed bytes and survives an interrupted connection.

Save yourself the typing with an SSH config entry. Add to ~/.ssh/config:

Host gpu
    HostName 192.168.1.100
    User ubuntu
    IdentityFile ~/.ssh/gpu_key

Then just:

bash
ssh gpu

Downloading and unpacking things once you're connected:

bash
wget https://huggingface.co/model/resolve/main/model.safetensors  # Download a model
curl -O https://example.com/data.tar.gz                            # Same thing with curl
tar xzf dataset.tar.gz -C ./data/                                   # Untar a dataset

WSL2 for Windows Users

If you're on Windows, WSL2 gives you a real Linux environment without dual-booting.

bash
# In PowerShell (admin)
wsl --install -d Ubuntu-24.04
 
# After restart, open Ubuntu from the Start menu
sudo apt update && sudo apt upgrade -y

WSL2 runs a real Linux kernel. Everything in this lesson works inside it. Your Windows files are at /mnt/c/Users/YourName/ from inside WSL.

GPU passthrough works with NVIDIA drivers installed on the Windows side. Install the Windows NVIDIA driver (not the Linux one), and CUDA is available inside WSL2.

Aliases and Common AI Terminal Patterns

~/.bashrc and ~/.zshrc are files your shell automatically reads (sources) every time it starts, so anything you put there, like an alias, becomes available in every new terminal you open. Add these to ~/.bashrc or ~/.zshrc:

bash
source phases/00-setup-and-tooling/04-the-command-line-and-linux/code/shell_aliases.sh

Or just copy the ones you want. The ones that pull their weight:

bash
# GPU status at a glance
alias gpu='nvidia-smi --query-gpu=index,name,utilization.gpu,memory.used,memory.total,temperature.gpu --format=csv,noheader'
 
# Kill all Python training processes
alias killtraining='pkill -f "python.*train"'
 
# Quick virtual environment activate
alias ae='source .venv/bin/activate'
 
# Watch training loss
alias watchloss='tail -f logs/*.log | grep --line-buffered "loss"'

See code/shell_aliases.sh for the full set.

A handful of patterns that come up repeatedly once you're actually running experiments:

bash
# Run training, log everything, notify when done
python train.py 2>&1 | tee train.log; echo "DONE" | mail -s "Training complete" [email protected]
 
# Compare two experiment logs side by side
diff <(grep "accuracy" exp1.log) <(grep "accuracy" exp2.log)
 
# Find the largest model files (clean up disk space)
find . -name "*.pt" -o -name "*.safetensors" | xargs du -h | sort -rh | head -20
 
# Count lines in all Python files (see how big your project is)
find . -name "*.py" | xargs wc -l | tail -1
 
# Environment variable check before training
env | grep -i cuda
env | grep -i torch
Check: Build It0/20
1. What does the pipe operator `|` do in a shell command?Define
Two terminal runs on the same six-line training log: cat train.log printing every line, then cat train.log | grep ERROR printing only the two ERROR lines.
2. What does `nohup` do to a command?Define
Terminal: nohup python train.py > train.log 2>&1 & prints a job number and process number, and jobs shows job 1 running. A note says the SSH window is about to be closed while train.py is still running.
3. What is tmux?Define
A terminal window split into two panes, one running python train.py with epoch loss lines and one running tail -f logs/experiment.log, under a green status bar reading [train] 0:python*. Below it, tmux ls lists two sessions, train and sweep.
4. What is SSH?Define
Terminal: hostname prints macbook, ssh ubuntu@203.0.113.7 prints an Ubuntu welcome line, then the prompt changes to ubuntu@gpu-box:~$ and hostname prints gpu-box and ls lists checkpoints, data and train.py.
Login banner and file names typed as an example, not captured here.
5. What makes rsync different from a plain copy?Define
Terminal: a data folder with labels.csv and three shard files of 300000, 600000 and 900000 bytes, then the output of the first rsync -av data/ remote/ run, which lists every file and the bytes sent.
First run of rsync into an empty destination.
6. Why pair `grep` with `awk` when pulling loss values out of a training log?Explain
A seven-line training log mixing loss lines, accuracy lines and a warning, followed by a card showing the wanted result: the three loss numbers 0.9124, 0.7310 and 0.5512, one per line.
7. Why does `python train.py &` still die when you close the SSH connection?Explain
Terminal: python train.py & prints a job and process number, jobs shows it running, then exit logs out and the connection to the GPU box closes. A note says that afterwards, train.py was meant to keep running.
8. You want GPU memory use and the process holding it, without installing anything extra. Which tool already does this?Explain
A card for a GPU box with nothing extra installed: a GPU memory bar partly filled with used and free amounts marked unknown, and a row saying python train.py holds it with PID and process name both unknown.
9. What is the key advantage of tmux over `nohup command &` for long training jobs?Explain
Two panels. Run A starts python train.py with nohup, output sent to train.log, in the background, then exits. Run B starts a tmux session named train, runs python train.py in it, detaches with Ctrl+B then d, then exits. Text says both started the same script on the same box and that you log in again later.
10. You are on Windows and want a real Linux environment for GPU work without dual-booting. What does the lesson recommend?Explain
PowerShell on Windows: grep and tmux each fail with a not recognized error. A card says the machine is a Windows laptop used for GPU work and the goal is Linux tools without dual-booting.
PowerShell error text typed in its usual format, not captured here.
11. What does `python train.py > output.log 2>&1` accomplish?Apply
Terminal: running python train.py prints three epoch loss lines tagged stdout and a WARNING line tagged stderr on screen, followed by the typed but not yet run command python train.py > output.log 2>&1.
Plain run first, with each line tagged by the stream it comes from.
12. In `grep "loss:" train.log | awk '{print $NF}'`, what does `$NF` extract?Apply
Terminal: a seven-line training log with the three loss lines highlighted, then the command grep "loss:" train.log | awk '{print $NF}' with its output not shown.
13. After adding the lesson's `gpu` alias (`nvidia-smi --query-gpu=... --format=csv,noheader`), you type `gpu`. What prints?Apply
The ~/.bashrc file with the alias gpu defined as nvidia-smi --query-gpu=index,name,utilization.gpu,memory.used,memory.total,temperature.gpu --format=csv,noheader, followed by a terminal prompt with gpu typed.
14. With `alias killtraining='pkill -f "python.*train"'` defined, which running process does it stop?Apply
The alias killtraining defined as pkill -f "python.*train", and ps -eo pid,args listing four running processes with their command lines: python train.py --epochs 100 --lr 1e-4, python serve.py --port 8000, tmux new -s train and tail -f train.log.
Four processes running on the box when the alias is typed.
15. Which command lets your local browser reach a Jupyter notebook running on port 8888 of a GPU box?Apply
Left, your laptop with a browser at localhost:8888 showing This site can't be reached, ERR_CONNECTION_REFUSED. Right, the GPU box where Jupyter Server is running at http://localhost:8888. A dashed line with a question mark joins them.
Browser error and Jupyter text typed in their usual wording, not captured here.
16. After adding a `Host gpu` entry with HostName, User and IdentityFile to `~/.ssh/config`, how do you connect?Apply
The file ~/.ssh/config with a Host gpu entry giving HostName 203.0.113.7, User ubuntu and IdentityFile ~/.ssh/gpu_key, above an empty terminal prompt waiting for a command.
17. You run `python train.py > output.log`, but error tracebacks still print on your screen instead of landing in the file. Why?Analyze
Terminal: python train.py > output.log prints a Traceback ending in RuntimeError: CUDA out of memory on screen, then cat output.log shows only the two epoch loss lines.
18. A teammate says scp and rsync are interchangeable for a large dataset you re-upload daily after small edits. What is wrong with that view?Analyze
A card for dataset/, a large dataset re-uploaded to the GPU box every day with only small edits in between, drawn as a long bar for the whole dataset and a short bar for the daily edits, not to scale.
19. You must copy a 50GB dataset to a GPU box over Wi-Fi that keeps dropping. Which tool fits, and why?Design
A laptop holding a 50 GB dataset and a GPU box with an empty data folder, joined by a dashed red line labeled Wi-Fi keeps dropping. A progress bar shows a transfer stopped partway, with a copied part and a not copied yet part.
20. You will run a 12-hour training job on a rented box, watch GPU use and logs as it goes, and your laptop will sleep overnight. Which setup fits?Design
A timeline of a 12-hour training job from hour 0 to hour 12, with a span in the middle marked overnight, laptop asleep. A card says you also want live GPU utilization and the scrolling training log while it runs.

Use It

Here's when each of these actually comes up as you move through the rest of the course:

ToolWhen you use it
Filesystem nav, chmod, aptSetting up any fresh GPU box, day one
tmuxEvery training run from Phase 3 onward
tail -f + grepMonitoring training logs
nohup / &Quick background tasks that don't need a full tmux session
htop / nvtopDebugging slow training, OOM errors
SSH + rsync / scpWorking on rented cloud GPUs
Piping + redirectsProcessing experiment results
df / duWhenever a disk fills up with checkpoints
AliasesSaving time on repetitive commands
Author's Note

I almost kept these as two separate lessons: Linux-the-operating-system on one side, terminal-the-tool on the other. But you never actually learn them that way. You SSH into a box, ls around to get oriented, hit a permissions error, fix it with chmod, start training in a tmux pane, and pipe the log through grep, all inside the same five minutes. The line between "this is Linux" and "this is the terminal" doesn't exist in practice, so it shouldn't exist in the lesson either.

Exercises

  1. SSH into any Linux machine (or open WSL2) and navigate to your home directory. Create a project folder with mkdir -p, create three empty files inside it with touch, list them with ls -la, then chmod +x one of them and confirm the change with ls -l.
  2. Install htop and nvtop with apt. Start a tmux session with three panes: htop in one, watch -n1 nvidia-smi (or watch -n1 date if you don't have a GPU) in another, and a running Python script in the third. Detach, then reattach.
  3. Create a fake training log with for i in $(seq 1 100); do echo "epoch $i loss: $(echo "scale=4; 1/$i" | bc)"; sleep 0.1; done > fake_train.log and use grep, tail, and awk to extract just the loss values.
  4. Add the aliases from code/shell_aliases.sh to your shell config and reload with source ~/.zshrc (or ~/.bashrc).
  5. Set up an SSH config entry for a server you have access to (or localhost, to practice the syntax), then transfer a file to it once with scp and once with rsync and compare the experience.
  6. Use df -h to check available disk space, then du -sh ~/.cache/* (or any large directory) to find what's actually taking up the room.

Key Terms

TermWhat people sayWhat it actually means
Shell"The terminal"The program that interprets your commands (bash, zsh, fish)
tmux"Terminal multiplexer"A program that lets you run multiple terminal sessions inside one window, and detach/reattach without killing what's running inside
Pipe"The bar thing"The | operator that sends one command's output as input to another
PID"Process ID"A unique number assigned to every running process, used to monitor or kill it
nohup"No hangup"Runs a command immune to the hangup signal, so closing the terminal won't kill it
SSH"Connecting to the server"Secure Shell, an encrypted protocol for running commands on a remote machine
chmod"Making it executable"Changes a file's read/write/execute permission bits for owner, group, and everyone else
sudo"Root mode"Temporarily elevates a single command to root (administrator) privileges
apt"Installing stuff on Linux"Ubuntu/Debian's package manager for system-level software
systemd"The thing that runs services"Linux's init system and service manager, which starts, stops, and restarts background daemons
rsync"Better scp"A file-sync tool that transfers only changed bytes and resumes on a dropped connection

Code