0 / 15 lessons — 0%
Lesson 08 / 15

Shell scripting essentials

The moment you've typed the same three commands in a row twice, it's worth turning them into a script. Bash scripting is 90% muscle memory around a small set of patterns.

#!/usr/bin/env bash set -euo pipefail # stop on error, undefined var, or a failed pipe stage — always include this APP_DIR="/opt/myapp" LOG_FILE="/var/log/myapp-deploy.log" if [ ! -d "$APP_DIR" ]; then echo "Creating $APP_DIR" mkdir -p "$APP_DIR" fi for service in nginx postgresql redis; do if systemctl is-active --quiet "$service"; then echo "$service is running" else echo "WARNING: $service is down" | tee -a "$LOG_FILE" fi done
PieceWhat it does
set -euo pipefail-e exit on any error, -u error on undefined variables, -o pipefail catch failures inside a pipe, not just the last command
$?the exit code of the last command — 0 means success, anything else is an error
$1, $2...positional arguments passed to the script
"$VAR"always quote variable expansions — unquoted variables break on spaces
chmod +x deploy.sh ./deploy.sh echo $? # check the exit code of the script that just ran
The three-line habit that prevents the most pain: start every real script with #!/usr/bin/env bash then set -euo pipefail. Without it, a script silently continues past a failed command and does damage three lines later with no clue why.
Try it yourselfWrite a 5-line script that loops over three service names and prints whether each is active, like the example above — then deliberately remove set -euo pipefail and reference an undefined variable to see the (lack of) error. That gap is exactly what the flag closes.