Skip to content
AgileLogics
5 min read

Local Variables and Return Values

Prerequisites: Functions

Variables are global by default

In Bash, a variable set inside a function is visible everywhere — which can silently overwrite variables elsewhere:

name="Ada"

change_name() {
  name="Linus"
}

change_name
echo "$name"
Linus

Use local

local limits a variable to the function (and functions it calls):

name="Ada"

change_name() {
  local name="Linus"
  echo "Inside: $name"
}

change_name
echo "Outside: $name"
Inside: Linus
Outside: Ada

Declare every variable inside a function with local unless you deliberately want to change a global one.

"Returning" values

Bash functions don't return values the way other languages do. There are two separate mechanisms:

1. Output a result, and capture it with $(...):

to_upper() {
  local text=$1
  echo "${text^^}"
}

result=$(to_upper "hello")
echo "Result: $result"
Result: HELLO

2. Return a status (0–255) with return, for success or failure:

is_even() {
  local n=$1
  (( n % 2 == 0 ))
}

for n in 3 4; do
  if is_even "$n"; then
    echo "$n is even"
  else
    echo "$n is odd"
  fi
done
3 is odd
4 is even

is_even has no explicit return: a function's status is the status of its last command — here, the (( )) test. Functions like this read naturally in if statements.

Common mistakes

  • Using return 42 to return data. The status is limited to 0–255 and is meant for success/failure. Print data instead.
  • Writing local result=$(command) and then checking $? — local itself succeeds, hiding the command's failure. Declare first (local result), then assign (result=$(command)).