Bash Scripting for DevOps: Variables, Loops, Functions, and Error Handling
Variables and Quoting
name="shellgenius"
echo "${name}" # expand variable
echo '${name}' # literal string (single quotes)
echo "${name:-default}" # use default if unset/empty
echo "${name:?'required'}" # exit with error if unset
echo "${#name}" # length
echo "${name^^}" # uppercase
---
Conditionals
# File tests
[ -f /etc/nginx.conf ] && echo "exists"
[ -d /var/log ] && echo "is directory"
[ -x /usr/bin/python3 ] && echo "executable"
# String tests
[ -z "$token" ] && { echo "token required"; exit 1; }
[ "$env" = "production" ] && echo "prod"
# Numeric
[ "$count" -gt 10 ] && echo "over 10"
# Pattern matching (bash only)
[[ "$file" == *.log ]] && echo "log file"
---
Loops
for host in web01 web02 web03; do
ssh "$host" "uptime"
done
for f in /var/log/*.log; do gzip "$f"; done
while IFS= read -r line; do
echo "Line: $line"
done < /etc/hosts
until curl -sf http://localhost:8080/health; do
sleep 2
done
---
Functions
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$1] $2"
}
retry() {
local max="$1" delay="$2"; shift 2
local attempt=1
until "$@"; do
[ "$attempt" -ge "$max" ] && return 1
log WARN "Attempt $attempt failed. Retrying in ${delay}s..."
sleep "$delay"; ((attempt++))
done
}
retry 3 5 curl -sf https://api.example.com/health
---
Error Handling
#!/usr/bin/env bash
set -euo pipefail
cleanup() { rm -f /tmp/work.$; }
trap cleanup EXIT
trap 'echo "Error on line $LINENO"' ERR
# Check a command explicitly
if ! systemctl is-active --quiet nginx; then
echo "nginx is not running" >&2; exit 1
fi
---
Argument Parsing
ENV="staging"; VERSION="latest"
while [[ $# -gt 0 ]]; do
case "$1" in
--env) ENV="$2"; shift 2 ;;
--version) VERSION="$2"; shift 2 ;;
*) echo "Unknown: $1"; exit 1 ;;
esac
done
Practice bash in the ShellGenius Linux Labs — the bash-scripting and bash-parallel-pipeline challenges use multi-step real-world scenarios.