After this lesson, you will be able to: Write bash scripts with variables, conditionals, loops, and functions to automate real tasks like backups, deploys, and log rotation.
Shell scripting is how ops engineers turn ad-hoc commands into repeatable automation. This lesson covers the syntax + the safety habits that prevent disasters.
Every production bash script starts with these. Memorise them.
#!/usr/bin/env bashset -euo pipefailIFS=$'\n\t'# Why each:# -e exit on any error# -u exit on undefined variable# -o pipefail exit if any part of a pipe fails# IFS prevent word-splitting bugs on filenames with spaces# Without these, scripts silently swallow failures.
Cover sheet of bash syntax.
name='alex' # no spaces around =echo "Hello, $name"echo "Date: $(date +%Y-%m-%d)"# Conditionalif [[ -f /etc/passwd ]]; thenecho 'exists'elif [[ -d /etc ]]; thenecho 'dir'elseecho 'no'fi# String comparison: == ; numeric: -eq -lt -gtif [[ "$1" == 'deploy' ]]; then ...if (( count > 5 )); then ...# Loopsfor f in *.log; do echo "$f"; donefor i in {1..5}; do echo "$i"; donewhile read -r line; do echo "$line"; done < input.txt# Functionsbackup() {local src="$1"local dest="$2"tar -czf "$dest" "$src"}backup /var/www /backups/www-$(date +%F).tar.gz
Drop this in /usr/local/bin/deploy.sh, chmod 755, run via cron or systemd timer.
#!/usr/bin/env bashset -euo pipefailIFS=$'\n\t'APP_DIR=/srv/myappREPO=https://github.com/me/myappLOG=/var/log/myapp/deploy.loglog() {echo "[$(date '+%F %T')] $*" | tee -a "$LOG"}log 'Starting deploy'cd "$APP_DIR"log 'Pulling latest'git fetch --all --quietgit reset --hard origin/mainlog 'Installing dependencies'npm ci --omit=devlog 'Building'npm run buildlog 'Restarting service'sudo systemctl restart myapplog 'Done'
`bash -n script.sh`, syntax check without running. `bash -x script.sh`, print each command as it runs (debugger). `shellcheck script.sh`, static analysis catches 80% of bash bugs. INSTALL IT. Run scripts in a test directory before pointing at production. `set -x` inside the script turns on tracing; `set +x` turns it off.
Skipping `set -euo pipefail`. Without it, errors silently propagate. Unquoted variables. `rm $FILE` with $FILE empty is `rm` (lists files); with a space, splits incorrectly. Always quote: `rm "$FILE"`. Trusting `cd` to succeed. `cd /nonexistent && rm -rf *` is a horror story without `set -e`. Using `eval`. Almost never necessary; almost always a security hole. Skipping shellcheck. It catches gotchas you wouldn't.
Pick the failure mode.
Sign in and purchase access to unlock this lesson.