Functions & arguments
Group commands into reusable units, accept positional parameters, and return exit codes. Not quite like functions in 'real' languages.
Define a function with name() { ... } or function name { ... }. Call it by name — no parentheses at the call site: greet alice (not greet(alice)). Arguments become positional parameters $1, $2, etc. — the SAME syntax as script-level args.
Example: greet() { echo "hello $1"; } — then greet world prints hello world. $1 inside the function is world, not the script's first argument. Functions have their own positional parameter scope.
Return values: return N sets the exit code (0-255 only). There is no 'return a value' like in Python. To return data, print it and capture with $(...): name=$(get_name). To return success/failure, use return 0 / return 1.
Local variables: by default all variables are global. local x=5 inside a function makes x local. Without local, you're silently mutating globals — a classic source of bugs in large scripts.
Example useful function:die() { echo "Error: $*" >&2; exit 1; } — prints to stderr and exits. Use as [[ -f $config ]] || die "config not found". Small reusable helpers like this clean up scripts dramatically.
Grounded on https://www.gnu.org/software/bash/manual/bash.html#Functions
Next up
Globbing & expansions
Wildcards for filenames, brace expansion for lists, parameter expansion for string ops. The shell rewrites your command line before running it.