published
priority 14
30 min. 50 XP.
Basic Shell Scripting. The 80% That Gets Things Done
You will write small bash scripts during the competition. backup-and-restore, health checks, config-diff alerts. This lesson covers the 80% of bash you need: shebangs, quoting, conditionals, loops, exit codes, and the pipe model.
Objectives
- Write a script that starts with `#!/bin/bash` and has +x permission
- Use `$1`, `$2`, `$@`, `$#` to take command-line args
- Quote correctly: single quotes (literal), double quotes (expand), backticks/$()
- Use `if`, `elif`, `else`, `case` for branching
- Use `for` and `while` loops
- Interpret exit codes and chain with `&&` and `||`
- Redirect output: `>`, `>>`, `2>`, `2>&1`, `&> file`
Quick reference
| Command | Purpose |
|---|---|
| #!/bin/bash | Shebang line. tells kernel to use bash |
| chmod +x script.sh | Make executable |
| set -euo pipefail | Fail fast: exit on error, undefined var, pipe failure |
| "$var" vs '$var' | Double = expand, single = literal |
| $(cmd) vs `cmd` | Command substitution; $() is preferred (nestable) |
| [[ "$a" == "$b" ]] | String equality (bash test) |
| [[ -f /path/file ]] | File exists and is regular |
| [[ -d /path/dir ]] | Path is a directory |
| echo $? | Exit code of last command (0 = success) |
| cmd1 && cmd2 | Run cmd2 only if cmd1 succeeded |
| cmd1 || cmd2 | Run cmd2 only if cmd1 FAILED |
| cmd &> log | Redirect stdout AND stderr to file |
| for i in *.conf; do echo $i; done | Glob loop |
| while read line; do echo $line; done < file | Read file line-by-line |
| trap 'echo interrupted' INT | Catch Ctrl-C |
Common pitfalls
- Forgetting to `chmod +x`. bash says 'Permission denied'
- Single-quoting a variable: `echo '$USER'` prints `$USER`, not the value
- Spaces around `=` in assignments: `x = 5` is wrong, `x=5` is right
- `if [ $var = 'x' ]` blows up when $var is empty. use `if [[ $var = 'x' ]]` (bash) or quote: `if [ "$var" = 'x' ]`
- Piping to `while read` creates a subshell. variables set inside are lost outside. Workaround: process substitution `while read . ; done < <(cmd)`
- Running a script with `bash script.sh` vs `./script.sh`. the first ignores the shebang
How it works (walkthrough)
#!/bin/bash
# restore-loop.sh. keep critical configs pristine
set -euo pipefail
GOLDEN=/root/golden-configs.tar.gz
LOG=/root/restore.log
while true; do
if [[ -f "$GOLDEN" ]]; then
tar -xzf "$GOLDEN" -C / 2>/dev/null
for svc in sshd smbd named apache2 postgresql; do
if systemctl is-active --quiet "$svc"; then
systemctl reload-or-restart "$svc" 2>/dev/null || true
fi
done
echo "$(date '+%F %T') restore cycle" >> "$LOG"
fi
sleep 60
done
Skill drills
-
1. What's a shebang line?#!/path/to/interpreter on line 1. tells kernel what runs the script
-
2. Diff between $() and backticks?$() is nestable and preferred; both do command substitution
-
3. What does `set -e` do in a script?Exit immediately on any command failure
-
4. Exit code of a successful command?0
-
5. What's the difference between `>` and `>>`?> overwrites the file; >> appends
-
6. How do you redirect stderr to stdout?2>&1
-
7. Shell operator that runs next command only if previous succeeded?&&