Control and functions
Write small functions
Extract repeated work into functions that accept arguments and return useful status.
10 minute lesson
A shell function is a named block of commands. It shares the script environment — same variables, same working directory — so it behaves less like a function in JavaScript or Python and more like a labeled section of your script. Keep it small, use local variables, and return status through command success.
Define one focused helper
require_command() {
local name=$1
command -v "$name" >/dev/null 2>&1 || {
printf 'missing command: %s\n' "$name" >&2
return 1
}
}
require_command curl || exit 1
Inside a function, $1, $2, and $# refer to the function’s own arguments, not the script’s. local name=$1 gives the value a readable name that exists only inside the function.
return sets the function’s exit status the way exit sets the script’s. A function without an explicit return reports the status of its last command — the same rule scripts follow.
Verify both outcomes
Call it with an installed and missing command:
require_command curl
printf '%s\n' "$?"
# 0
require_command doesnotexist
# missing command: doesnotexist
printf '%s\n' "$?"
# 1
The function’s output helps humans; its return status helps the caller. Keep the two channels separate: messages to standard error, results through the status.
The failure mode: hidden globals
Forget local and every variable a function touches leaks into the whole script:
count_lines() {
file=$1 # no local — overwrites any outer $file
wc -l < "$file"
}
file=config.txt
count_lines access.log
printf '%s\n' "$file"
# access.log — the caller's variable was silently replaced
These bugs are miserable to find because the damage appears far from the function that caused it. Avoid hidden global mutations: pass values in as arguments and mark internal variables local.
When a function needs to hand a value back, print it and let the caller capture it with command substitution:
lines=$(count_lines access.log)
That keeps data flowing through explicit channels — arguments in, output and status out — which is what makes a function safe to reuse.
Lesson completed