29Linux & Shell for SDET
What you will master here
- Filesystem layout + permissions
- Navigating + searching files (find, grep, sed, awk)
- Pipes, redirects, exit codes
- Processes, jobs, signals
- Networking basics (curl, netstat, ss, lsof)
- Shell scripting for test infra
- Environment variables, dotfiles
- SSH + scp essentials
29.1 Filesystem & permissions
/etc # system config /var/log # log files /tmp # temp (cleared on reboot) /home/x # user home (~/ shortcut) /usr/bin # standard programs /opt # third-party software # Permissions: rwx for owner, group, others ls -l file.txt # -rw-r--r-- 1 yash staff 200 ... chmod 755 script.sh # rwxr-xr-x chmod +x script.sh # add execute chown user:group f # change owner sudo cmd # run as root
chmod numeric reference
| Digit | Means |
|---|---|
| 7 (rwx) | read + write + execute |
| 6 (rw-) | read + write |
| 5 (r-x) | read + execute |
| 4 (r--) | read only |
| 0 (---) | none |
29.2 Navigation & search
cd ~/work; cd - # toggle to previous dir
ls -lah # long, hidden, human-readable sizes
tree -L 2 # 2 levels deep
# find — by name, type, size, mtime
find . -name "*.spec.ts"
find . -type f -size +1M # files larger than 1MB
find . -mtime -1 # modified in last 24h
find . -name "*.log" -delete
# grep — by content
grep -rni "TODO" src/ # recursive, case-insensitive, line numbers
grep -l "pattern" -r . # only filenames
grep -E "fail|error" test.log # extended regex (alt: egrep)
grep -v "debug" # invert match
grep -A 3 -B 2 "error" log.txt # context lines
# sed — stream edit
sed -i 's/foo/bar/g' file.txt # in-place replace
sed -n '10,20p' file.txt # print lines 10-20
# awk — field-aware
awk '{print $1, $3}' file # columns 1 and 3
awk -F',' '{sum += $2} END {print sum}' data.csv # sum column 2
29.3 Pipes, redirects, exit codes
cmd1 | cmd2 # stdout of 1 → stdin of 2 cmd > file # stdout → file (overwrite) cmd >> file # append cmd 2> err.log # stderr → file cmd > out 2>&1 # both stdout + stderr → file cmd < input.txt # stdin from file cmd1 && cmd2 # run cmd2 only if cmd1 succeeded cmd1 || cmd2 # run cmd2 only if cmd1 failed cmd1 ; cmd2 # run both regardless # Exit code of the last command echo $? # 0 = success, nonzero = failure # CI scripts rely on this — fail the build on nonzero
29.4 Processes, jobs, signals
ps aux | grep playwright # list processes top # interactive process viewer htop # nicer alternative kill 12345 # SIGTERM (polite) kill -9 12345 # SIGKILL (force) pkill -f playwright # kill by name pattern # Background jobs long-cmd & # run in background jobs # list shell jobs fg # bring last back to foreground bg # resume in background disown # detach so it survives shell exit nohup long-cmd & # immune to SIGHUP, output → nohup.out
29.5 Networking
curl -i https://api.example.com/users # show headers
curl -X POST -H 'Content-Type: application/json' -d '{"x":1}' url
curl -u user:pass url # basic auth
curl -o file.zip url # save to file
curl -w "%{http_code} %{time_total}s\n" url # custom timing
# Port checks
nc -vz host 5432 # is port open?
ss -tlnp # listening TCP sockets (modern netstat)
lsof -i :3000 # who's using port 3000?
# DNS
dig example.com # query DNS
nslookup example.com
host example.com
# Network tools
ping example.com
traceroute example.com
mtr example.com # combo ping + traceroute
29.6 Shell scripting essentials
#!/usr/bin/env bash
set -euo pipefail # exit on error, undefined var, pipe failure
NAME="${1:-default}" # first arg or 'default'
echo "Hi, $NAME"
# Conditions
if [[ -f config.yml ]]; then
echo "config exists"
fi
if [[ "$ENV" == "prod" || "$ENV" == "staging" ]]; then
echo "remote env"
fi
# Loops
for f in *.log; do
gzip "$f"
done
# Functions
log() { echo "[$(date -Iseconds)] $*"; }
log "starting"
# Command substitution
COUNT=$(ls -1 | wc -l)
LATEST=$(ls -t | head -1)
# Arrays
files=(a.txt b.txt c.txt)
for f in "${files[@]}"; do echo "$f"; done
29.7 Environment variables & dotfiles
export DATABASE_URL=postgres://localhost/test echo $DATABASE_URL env # all env vars unset DATABASE_URL # Where envs live ~/.bashrc # per-shell config (bash) ~/.zshrc # zsh ~/.profile # login shells ~/.bash_profile # Project-local .env # loaded by dotenv libs (not the shell) direnv # auto-load .envrc when you cd into a dir
29.8 SSH + scp
# Generate key ssh-keygen -t ed25519 -C "you@host" cat ~/.ssh/id_ed25519.pub # add this to GitHub / server # Connect ssh user@host ssh -i ~/.ssh/key.pem user@ec2-host ssh -p 2222 user@host # custom port # Run remote command + return ssh user@host "ls /var/log" # Copy files scp file.txt user@host:/tmp/ scp -r dir/ user@host:~/ # Tunnel local → remote ssh -L 5432:db.internal:5432 jump-host # now local localhost:5432 → db.internal:5432 via jump-host
29.9 Useful SDET one-liners
# Count test failures in a JUnit XML grep -c '<failure' results.xml # Largest files du -sh */ | sort -h | tail -10 # Tail logs from multiple files tail -f app.log db.log | grep -i error # Wait for a port to open before continuing (in CI) until nc -z localhost 3000; do sleep 1; done # Free disk per partition df -h # Memory + CPU snapshot top -b -n 1 | head -20 # Find tests last modified in past day find tests -name "*.spec.ts" -mtime -1
Module 51 — Linux Q&A
How do you check if a port is in use?
lsof -i :3000 shows the process. ss -tlnp lists all listening sockets. nc -vz host port tests reachability from another host.What does set -euo pipefail do?
Defensive bash. -e: exit on any command failure. -u: error on undefined variable. -o pipefail: pipeline fails if ANY command in it fails (not just the last). Put at top of every script.
Difference between > and >>?
> overwrites the file. >> appends. Same for 2> vs 2>> with stderr.How do you redirect stderr to stdout?
cmd 2>&1 — sends stderr to wherever stdout currently goes. Common pattern: cmd > all.log 2>&1 sends both to all.log.How do you find files modified in the last hour?
find . -mmin -60 for minutes; find . -mtime -1 for the last day. Combine with -name and -size for tighter filters.What's the difference between grep -l and grep -L?
-l prints only files that MATCH. -L prints only files that DON'T match. Useful with xargs for follow-up actions.
What's $??
Exit code of the previous command. 0 = success, nonzero = failure. CI scripts depend on it to know whether a step succeeded.
How do you wait for a service to be ready in CI?
Poll loop:
until nc -z localhost 3000; do sleep 1; done. Or use a health endpoint: until curl -fs localhost:3000/health; do sleep 1; done. Add a timeout to avoid forever-waits.What's nohup for?
"No hangup" — makes a command immune to the HUP signal when the shell exits.
nohup long-task & survives SSH disconnect. Output goes to nohup.out by default.SIGTERM vs SIGKILL?
SIGTERM (15): polite shutdown — process can catch it and clean up. SIGKILL (9): unconditional kill, kernel removes the process. Always try SIGTERM first.
How does an SSH tunnel work?
ssh -L localPort:targetHost:targetPort jumpHost forwards localhost:localPort over the SSH connection to jumpHost, which then forwards to targetHost:targetPort. Used to reach internal services from your laptop.What's the difference between .bashrc and .bash_profile?
.bash_profile runs for LOGIN shells (SSH session, console). .bashrc runs for INTERACTIVE non-login shells (new terminal window after login). Most setups source .bashrc from .bash_profile so both work the same.