Unix / Linux Essentials
Filesystem layout, the commands you actually use (find / grep / awk / sed / xargs), processes and signals, networking, permissions, basic shell scripting, and a vi survival kit.
Why this matters
Unix-fluency shows up in three interview moments: a system-design discussion that drops into how you'd debug a hot host, an SRE / platform round that grills tooling, and the take-home where the reviewer judges your shell hygiene. The shell is also where 90% of incident response happens. Knowing the right command in the right shape is faster than reaching for any GUI, every time.
Filesystem layout (FHS)
The standard directory roles. Most Linux distros follow the Filesystem Hierarchy Standard.
- /
- Root of the filesystem. Everything else hangs off this.
- /bin, /sbin
- Essential user / system binaries available in single-user mode. Modern distros symlink these to /usr/bin and /usr/sbin.
- /usr/bin, /usr/sbin
- Non-essential user / admin binaries installed by the distro.
- /usr/local
- Locally-installed software (not managed by the distro package manager). /usr/local/bin is conventional for hand-installed tools.
- /etc
- System-wide configuration. Read on boot or by daemons. /etc/hosts, /etc/passwd, /etc/ssh/sshd_config.
- /var
- Variable data: logs (/var/log), spool (/var/spool), caches (/var/cache), state (/var/lib).
- /tmp
- Temporary files. World-writable + sticky bit. Often cleared on reboot. Don't rely on persistence.
- /home
- User home directories. /home/alice. Typically the only writable location for non-root users.
- /proc
- Pseudo-filesystem exposing kernel + process state. /proc/cpuinfo, /proc/meminfo, /proc/<pid>/status.
- /sys
- Pseudo-filesystem for kernel-exposed device + driver state. Used by udev, lsblk.
- /dev
- Device nodes. /dev/null, /dev/zero, /dev/random, /dev/sda, /dev/tty.
- /opt
- Self-contained third-party software (typically vendor-installed): /opt/<vendor>/<product>.
Files and search
Find files, search inside files, transform text. find + grep + xargs is the workhorse triple.
| Command | What it does | Common flags | Example |
|---|---|---|---|
| ls | List directory contents. | -l (long), -a (incl. dotfiles), -h (human sizes), -t (sort by mtime), -S (sort by size), -1 (one per line) | ls -lah /var/log |
| find | Recursive file search by name, type, size, mtime, etc. | -name, -iname, -type f|d, -size, -mtime, -newer, -maxdepth, -exec ... \; | find . -type f -name '*.log' -mtime -1 -exec gzip {} \; |
| grep | Regex search inside files. | -r (recursive), -n (line numbers), -i (case-insensitive), -E (extended regex), -v (invert), -l (list files only), -A/-B/-C (context) | grep -rn --include='*.ts' 'TODO' src/ |
| rg (ripgrep) | Faster grep with sane defaults (gitignore-aware, recursive by default). Not POSIX but ubiquitous in modern dev environments. | -i, -n, -t TYPE, -g GLOB, --hidden | rg -t ts 'TODO\|FIXME' |
| awk | Field-aware text processor. Default field separator is whitespace. Each line -> $0; fields are $1, $2, .... | -F (field separator), -v (var assignment) | awk -F: '$3 >= 1000 { print $1 }' /etc/passwd # human users |
| sed | Stream editor for line-oriented substitution and deletion. | -i (in-place), -E (extended regex), -n (suppress) | sed -i.bak 's/foo/bar/g' file.txt # in-place with .bak backup |
| xargs | Build command lines from stdin. Pairs with find / ls / grep -l. | -0 (NUL-delimited), -n (max args/cmd), -P (parallel), -I (replace token) | find . -name '*.tmp' -print0 | xargs -0 rm # NUL-safe deletes |
| sort / uniq | Sort lines / collapse adjacent duplicates. | sort: -n (numeric), -k N (key field), -r (reverse), -u (unique). uniq: -c (count), -d (dups only) | cut -d' ' -f1 access.log | sort | uniq -c | sort -rn | head |
| cut / tr / head / tail / wc | cut = extract columns. tr = translate / squeeze chars. head/tail = first/last N. wc = count lines/words/bytes. | cut -d -f. tr -s -d. head -n. tail -n -f (follow). wc -l -w -c | tail -n 100 -f /var/log/syslog |
| diff / patch | Compare files / apply diffs. | diff -u (unified), -r (recursive). patch -p1 | diff -u old.txt new.txt > my.patch |
| tar / gzip / zstd | Bundle + compress / decompress. | tar -czf out.tgz dir/ (create gzip). tar -xzf in.tgz (extract). gzip -k (keep). zstd -k -19 | tar -czf logs-$(date +%F).tgz /var/log/myapp/ |
Processes and signals
Inspect what's running, control it, and send the right signal when something is wedged.
| Command | What it does | Common flags | Example |
|---|---|---|---|
| ps | Snapshot of processes. | aux (all + user + mem), -ef (full format), -o (custom columns) | ps aux --sort=-%mem | head |
| top / htop | Interactive process monitor. htop is the friendlier color version. | Inside: P (sort cpu), M (sort mem), F2 (htop config), T (tree view) | htop |
| kill | Send a signal to a process. Default signal is TERM. | -l (list signals), -9 (KILL - immediate, no cleanup), -15 (TERM - graceful), -1 (HUP - reload config), -2 (INT - same as Ctrl+C) | kill -TERM 12345 # ask politely. Then -9 if it ignores you. |
| pkill / pgrep | Kill / find by name pattern. | -f (match full cmdline), -u USER | pkill -f 'python my-stuck-script' |
| nohup / & | Run a command immune to hangups (terminal close). & backgrounds. | Pipe stdout/err with > and 2>&1. | nohup ./long-job.sh > job.log 2>&1 & |
| jobs / fg / bg / disown | Manage shell-backgrounded jobs. fg foregrounds, bg resumes in background, disown detaches from shell. | %1, %2 (job specs) | Ctrl+Z; bg %1; disown %1 |
| lsof | List open files. Powerful: open files include sockets, devices, deleted-but-held files. | -i :PORT (network), -p PID, -u USER, +D DIR (recursive) | lsof -i :8080 # who's holding port 8080? |
| strace / ltrace | Trace syscalls / library calls of a running process. Last-resort debugging. | strace -p PID, -e trace=open,read, -c (summary), -f (follow forks) | strace -f -e trace=network -p 12345 |
Common signals
Send with kill -<NAME> <pid>. The defaults of TERM (15) and KILL (9) cover most needs.
- SIGHUP (1)
- Hangup. Conventionally used to tell daemons to reload config without restarting (nginx, syslog).
- SIGINT (2)
- Interrupt. What Ctrl+C sends. Apps can catch + clean up.
- SIGQUIT (3)
- Quit + core dump. Ctrl+\ in terminal.
- SIGKILL (9)
- Hard kill. Cannot be caught, blocked, or ignored. No cleanup. Use only when SIGTERM was ignored.
- SIGTERM (15)
- Polite shutdown. Default of kill. Apps catch this to flush, drain, then exit.
- SIGSTOP / SIGTSTP / SIGCONT (19/20/18)
- Stop / continue. Ctrl+Z sends TSTP; bg / fg sends CONT. SIGSTOP is uncatchable.
- SIGUSR1 / SIGUSR2 (10/12)
- Application-defined. Many daemons use these for log-rotate signals or runtime toggles.
- SIGPIPE (13)
- Write to a pipe with no reader. Default kills the process - the source of "why does my pipeline die when I head -1 it."
Networking
Inspect interfaces, sockets, DNS, HTTP. ss has replaced netstat on most distros.
| Command | What it does | Common flags | Example |
|---|---|---|---|
| ip | Modern replacement for ifconfig + route. Inspect / configure interfaces, addresses, routes. | ip addr, ip link, ip route, ip -s | ip -br addr # one-line per interface |
| ss | Socket statistics. Replaces netstat. Faster, friendlier output. | -t (TCP), -u (UDP), -l (listening), -n (no DNS), -p (process) | ss -tlnp # all listening TCP sockets with process |
| netstat | Older / portable equivalent of ss. Still common in older distros. | -tlnp, -an, -r (routes) | netstat -tlnp |
| curl | Make HTTP/S requests. Default GET. Supports almost every protocol. | -X METHOD, -H 'Header: val', -d 'body', -i (response headers), -I (HEAD only), -L (follow redirects), -k (skip TLS verify), -s (silent), -o file, -w '%{http_code}\n' | curl -isL -H 'Accept: application/json' https://api.example.com/v1/health |
| wget | Download files. Better than curl for recursive mirrors. | -c (continue), -r (recursive), -O (output name) | wget -c https://example.com/big.iso |
| dig | DNS query tool. | +short, +trace, +noall +answer, @8.8.8.8 (server), -t TYPE | dig +short A gitgood.dev |
| nslookup | Older DNS tool. dig is preferred. | (interactive or one-shot) | nslookup gitgood.dev |
| ping / traceroute / mtr | ICMP reachability / per-hop latency. mtr combines ping + traceroute interactively. | ping -c N -i SEC. traceroute -n. mtr -n -r -c 50 | mtr -rn -c 30 1.1.1.1 |
| nc (netcat) | Raw TCP/UDP swiss-army knife. Listen, scan, port-test, transfer files. | -l (listen), -v, -z (port scan), -u (UDP), -w (timeout) | nc -vz example.com 443 # is 443 open? |
| tcpdump | Packet capture. Use BPF filters to scope. | -i IFACE, -n (no DNS), -X (hex+ascii), -w file (pcap), 'port 80' (filter) | tcpdump -i eth0 -n 'host 1.2.3.4 and port 443' |
Permissions and ownership
Three actor classes (user, group, other) x three rights (read, write, execute). On directories, x means "can enter / traverse," not "can execute."
- Octal modes
- r=4, w=2, x=1. 755 = rwxr-xr-x (owner full, others read+exec). 644 = rw-r--r-- (owner write, others read). 600 = rw------- (owner only). 700 = rwx------ (private bin / dir).
- chmod
- chmod 644 file, chmod -R u+rwX,go=rX dir/. Symbolic: u (user), g (group), o (other), a (all). +/-/= (add/remove/set). X = exec only on dirs / already-exec files.
- chown / chgrp
- chown alice:devs file. chown -R alice:devs dir/. Requires root for cross-user changes.
- umask
- Default mask subtracted from 0777 (dirs) / 0666 (files) on creation. 022 -> dirs 755, files 644. 077 -> dirs 700, files 600 (paranoid).
- Special bits
- Setuid (4000) - run as file owner (e.g. /usr/bin/passwd). Setgid (2000) - run as group, or on dirs make new files inherit the dir's group. Sticky (1000) - on world-writable dirs, only the owner can delete their files (/tmp).
- sudo
- Run a command as another user (default: root). sudo -u alice cmd. sudo -i (interactive root shell). Configured in /etc/sudoers (edit with visudo).
Shell scripting essentials
Bash is the lingua franca. These idioms cover 90% of real scripts.
- ·#!/usr/bin/env bash - first line. Use env so the script honors PATH.
- ·set -euo pipefail - fail fast: -e exit on error, -u error on unset var, -o pipefail propagates errors through pipes. Add this to every non-trivial script.
- ·Variables: name=value (no spaces). Use "$name" with quotes to handle whitespace. Arrays: arr=(a b c); echo "${arr[@]}".
- ·Conditionals: if [[ -f "$file" ]]; then ...; fi. Prefer [[ ... ]] over [ ... ] in bash. Common tests: -f (file), -d (dir), -z (empty), -n (non-empty), -eq -ne -lt -gt (numeric).
- ·Loops: for x in *.txt; do ...; done. while read -r line; do ...; done < file.
- ·Command substitution: result=$(cmd). Don't use backticks (deprecated).
- ·Functions: foo() { local x=$1; echo "hi $x"; }. Always declare local for function-scoped vars.
- ·Trap cleanup: trap 'rm -f "$tmp"' EXIT - guarantees the temp file is cleaned up on any exit (success, error, signal).
- ·Process substitution: diff <(cmd1) <(cmd2). Pass command output where a filename is expected.
- ·Default values: ${var:-default} (use default if unset/empty). ${var:?error message} (fail if unset).
- ·Heredoc: cat <<EOF ... EOF. Use <<'EOF' (quoted) to disable variable expansion.
- ·$? - exit status of last command. 0 = success, non-zero = failure. $! - PID of last background command. $# - argument count. $@ - all args (use "$@" with quotes).
vi / vim survival kit
vi is on every Unix box you'll ever ssh into. You only need ~15 commands to be functional.
- ·Modes: NORMAL (default, navigation/commands), INSERT (typing text), VISUAL (selection), COMMAND-LINE (typed after :).
- ·Esc - back to NORMAL from any mode. (Press it twice if unsure.)
- ·i - insert before cursor. a - append after cursor. o - new line below + insert. O - new line above + insert.
- ·h j k l - left, down, up, right. (Use arrow keys if you don't have the muscle memory yet.)
- ·w / b - jump forward / back by word. 0 / $ - start / end of line. gg / G - top / bottom of file. <N>G - jump to line N.
- ·x - delete character. dd - delete line. dw - delete word. d$ - delete to end of line. D - same as d$.
- ·yy - yank (copy) line. yw - yank word. p - paste after cursor. P - paste before.
- ·u - undo. Ctrl+R - redo. . (period) - repeat last change.
- ·/pattern - search forward. ?pattern - search backward. n / N - next / previous match.
- ·:%s/old/new/g - replace all in file. :%s/old/new/gc - confirm each. :s/old/new/g - replace on current line.
- ·:w - save. :q - quit. :wq - save + quit. :q! - quit without saving (escape hatch when stuck).
- ·:set number - line numbers. :set paste / :set nopaste - toggle paste mode (use before pasting from terminal to prevent auto-indent disasters).
- ·v - VISUAL mode (char). V - VISUAL line mode. Then d (cut), y (copy), > / < (indent / dedent).
- ·:e <file> - open another file. :bn / :bp - next / previous buffer. :bd - close buffer.
- ·ZZ - save + quit (uppercase, no colon). ZQ - quit without saving. Faster than typing :wq.
Other cheat sheets
Big-O Reference
AlgorithmsTime and space complexity for the data structures, sorting algorithms, and search routines that show up in coding interviews. Skim the row, remember the row, defend the row in an interview.
Interview Patterns
PatternsThe recurring shapes - sliding window, two pointers, fast/slow, BFS/DFS, backtracking, DP, divide & conquer, binary search variants, union-find, topological sort. Each entry: when to reach for it, the template, complexity, and which classic problems use it.
Design Tradeoffs
SystemsThe recurring forks in system design interviews. CAP, PACELC, sync vs async, push vs pull, SQL vs NoSQL, sharding shapes, consistency models, cache strategies, idempotency, and rate limiting. For each, the options and when to choose each.
Practice the patterns
Reading is the floor. The signal in interviews comes from working problems out loud and defending your tradeoffs. Spin up an AI mock interview or run a coding challenge to put these to work.