Functions and Script ArchitectureLesson 3.2
Bash local variables and scope explained
global vs local scope, local keyword, dynamic scoping in Bash, function side effects, nameref variables, subshell scope, environment vs shell variables, export
Bash Has Dynamic Scoping
Bash uses dynamic scoping — a called function can see (and modify!) its caller's local variables. This is unlike most languages. The only protection is the local keyword.
result="initial"
modify_result() {
result="modified" # Modifies the GLOBAL variable
}
modify_result
echo $result # "modified" — side effect!
# Fix: use local in the calling function too
run_task() {
local result="initial"
modify_result # still modifies global 'result', not local!
echo $result # still "modified" because local doesn't affect callees
}The Safe Pattern
process_file() {
local file="$1" # always local for params
local line_count # declare first, assign separately
local output_dir="/tmp/processed"
line_count=$(wc -l < "$file")
echo "$file has $line_count lines"
}Shell vs Environment Variables
# Shell variable — visible only in current shell
my_var="hello"
# Environment variable — inherited by child processes
export DB_HOST="localhost"
# Or in one step:
export API_KEY="secret"
# Child processes see exported vars:
bash -c 'echo $DB_HOST' # prints: localhost
bash -c 'echo $my_var' # prints nothing — not exportedConfiguration that child scripts or programs need must be exported. API keys and database URLs are typically exported — or passed explicitly as arguments for better auditability.
