Script Valley
Bash Scripting for Developers
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 variable scope diagram

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 exported

Configuration 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.

Up next

Bash script structure and sourcing files

Sign in to track progress

Bash local variables and scope explained โ€” Functions and Script Architecture โ€” Bash Scripting for Developers โ€” Script Valley โ€” Script Valley