Automation & Scripting

Bash Scripting Essentials

40 min

Skeleton for every script

#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'

main() {
    echo "Hello from $(hostname)"
}

main "$@"
  • -e exit on error, -u error on unset variables, -o pipefail fail if any command in a pipe fails.
  • main "$@" passes all arguments through, keeping the script readable top to bottom.

Variables and quoting

name="PandaDev"            # no spaces around =
echo "Hello $name"         # double quotes expand variables
echo 'Hello $name'         # single quotes are literal
files=$(ls *.log)          # command substitution
count=$((3 + 4))           # arithmetic
echo "${name,,}"           # lowercase: pandadev
echo "${FILE:-default.txt}"   # default value if unset

Quote every variable: "$file", not $file. Unquoted variables split on spaces and expand wildcards, which is how scripts delete the wrong files.

Conditions

if [[ -f "$config" ]]; then
    echo "config exists"
elif [[ -d "$config" ]]; then
    echo "that is a folder"
else
    echo "missing" >&2
    exit 1
fi
Test True when
-f file regular file exists
-d dir directory exists
-z "$s" string is empty
"$a" == "$b" strings are equal
$n -gt 5 number greater than 5 (-lt, -eq, -ge...)

Loops

for f in /var/log/nginx/*.log; do
    echo "$f: $(wc -l < "$f") lines"
done

while read -r line; do
    echo "user: $line"
done < users.txt

for i in {1..5}; do echo "attempt $i"; done

Functions and arguments

log() { echo "[$(date -u +%H:%M:%S)] $*"; }

usage() {
    echo "Usage: $0 <environment> [--dry-run]" >&2
    exit 2
}

[[ $# -ge 1 ]] || usage
env="$1"
dry_run=false
[[ "${2:-}" == "--dry-run" ]] && dry_run=true

log "deploying to $env (dry run: $dry_run)"

$1, $2... are arguments, $# is how many, $@ is all of them.

Cleaning up, even on failure

tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT

trap ... EXIT runs when the script ends for any reason, so temporary files never pile up.

Check your scripts

Install ShellCheck (sudo apt install shellcheck) and run shellcheck script.sh. It catches unquoted variables and dozens of other bugs before they run.

Exercise

Write disk-alert.sh that prints a warning to stderr and exits with code 1 when any filesystem in df -P is above a percentage given as the first argument (default 80).

Seu progresso fica salvo apenas neste navegador.

Enviar para revisão (10 pontos)