Bash Scripting for Engineers›Modules · Cheat sheet & self-check

Modules · wrap-up

Cheat sheet & self-check

Every command from this section on one page.

01 · Scripts, variables & quoting

Basics

#!/usr/bin/env bashFirst line: run this file with bash
chmod +x script.sh && ./script.shMake executable and run
bash -x script.shRun with a trace of every command
name="Asha"Assign (no spaces around =)
echo "Hello, $name"Use a variable (inside double quotes)

Quoting

"$var"Double quotes: variables expand, no word splitting (use by default)
'$var'Single quotes: completely literal
today=$(date +%F)Command substitution: capture output
echo "$?"Exit status of the last command (0 = success)

02 · Conditions & loops

Tests inside [[ ]]

[[ -f file ]] / [[ -d dir ]]File exists / directory exists
[[ -z "$v" ]] / [[ -n "$v" ]]Empty / not empty
[[ "$a" == "$b" ]]Strings equal
[[ $name == web-* ]]Pattern match
(( n > 10 ))Numeric comparison

Loops

for host in web-01 web-02; do …; doneLoop over words
for f in /var/log/*.log; do …; doneLoop over files (glob)
for i in {1..5}; do …; doneLoop over a range
while IFS= read -r line; do …; done < fileRead a file line by line, safely
arr=(a b c); for x in "${arr[@]}"; do …; doneLoop over an array

03 · Functions & arguments

Arguments

$0The script's name
$1, $2 …Positional arguments
"$@"All arguments, each kept whole (quote it!)
$#Number of arguments
shiftDrop $1, move the rest down
${1:-default}Use a default if $1 is empty

Functions

log() { printf '%s %s\n' "$(date +%T)" "$*" >&2; }A logging helper that writes to stderr
local name="$1"Variable visible only inside the function
return 1Function failure status
result=$(my_func arg)Capture a function's output

04 · Text processing

sed

sed -n '10,20p' filePrint lines 10–20
sed 's/old/new/g' fileReplace every 'old' with 'new' (prints the result)
sed -i.bak 's/^Port 22$/Port 2222/' fileEdit in place, keeping file.bak
sed '/^#/d; /^$/d' fileDelete comments and blank lines

awk

awk '{print $1, $3}' filePrint columns 1 and 3
awk -F: '$3 >= 1000 {print $1}' /etc/passwdUsers with UID ≥ 1000
awk '{sum += $2} END {print sum}' fileSum a column
awk '$9 >= 500' access.log | wc -lCount 5xx lines (combined log format)

jq

jq '.items | length'Count items
jq -r '.items[].metadata.name'One name per line (raw)
jq -r '.items[] | select(.status.phase != "Running") | .metadata.name'Filter objects
jq -r '.[] | [.name, .size] | @csv'Output CSV

05 · Safe scripts

Strict mode

set -euo pipefailStop on errors, unset variables, and failures inside pipelines
trap 'echo "failed at line $LINENO" >&2' ERRReport where it failed
trap cleanup EXITAlways run cleanup, success or failure
${VAR:?VAR must be set}Abort with a message if VAR is empty

Safety patterns

tmp=$(mktemp -d)A private temporary directory
exec 9>/var/lock/myjob.lock; flock -n 9 || exit 0Only one copy runs at a time
mkdir -p, ln -sfn, cp -nIdempotent building blocks
rm -rf -- "${dir:?}"/Refuse to run if dir is empty

06 · Scheduling & automation

cron

crontab -eEdit your user's crontab
crontab -lList it
*/15 * * * * /opt/bin/job.shEvery 15 minutes
30 2 * * 1-5 /opt/bin/job.sh02:30 on weekdays
0 3 1 * * /opt/bin/job.sh03:00 on the 1st of every month

systemd timers

systemctl list-timersAll timers with their next and last runs
systemd-analyze calendar 'Mon..Fri 02:30'Check an OnCalendar expression
sudo systemctl start backup.serviceRun the job now, on demand
journalctl -u backup.service --since todayThe job's logs

07 · Testing & linting

Lint & format

shellcheck script.shFind bugs: unquoted variables, bad tests, unused vars…
shellcheck -x script.shAlso follow 'source'd files
shfmt -d -i 2 script.shShow formatting differences (2-space indent)
shfmt -w -i 2 script.shRewrite the file formatted

bats

bats tests/Run all .bats test files
run my_function argCall something and capture $status and $output
[ "$status" -eq 0 ]Assert success
[[ "$output" == *"expected"* ]]Assert output contains text

08 · Capstone: a real ops script

Exit codes used by healthcheck.sh

0All checks passed
1At least one check failed
2Usage error
3A required tool is missing

Run it

./healthcheck.sh -c checks.confRun checks from a file
./healthcheck.sh -c checks.conf -w https://hooks.example.com/…Also send an alert on failure
systemctl list-timers healthcheck.timerWhen it runs next