Functions and exit status

Define functions, read arguments with $1 and "$@", return a status, output a value, and stop on errors with set -euo pipefail.

Runs in Zerethon IDE · Bash 5.2 Official Bash documentation ↗

Every command ends with an exit status: 0 means success, anything else is failure. if and && / || test that status. A function returns a status with return, and hands back data by printing it.

main.sh
greet() {
  local name="$1"
  local greeting="${2:-Hello}"
  echo "$greeting, $name!"
}

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

sum() {
  local total=0 n
  for n in "$@"; do
    (( total += n ))
  done
  echo "$total"
}

greet "Ada"
greet "Linus" "Hi"
result=$(sum 4 8 6)
echo "sum: $result"
if is_even 10; then echo "10 is even"; fi
is_even 7 || echo "7 is odd (status $?)"

Output

Hello, Ada!
Hi, Linus!
sum: 18
10 is even
7 is odd (status 1)
main.sh
set -euo pipefail
trap 'echo "cleanup on exit"' EXIT

echo "start"
value=$(echo "42")
echo "value: $value"
grep -q "x" <<< "abc" || echo "no x found"
status=0
bash -c 'set -e; false; echo "never printed"' || status=$?
echo "inner script stopped with status $status"

Output

start
value: 42
no x found
inner script stopped with status 1
cleanup on exit
With set -e a script stops at the first command that fails: the inner script never reaches its echo. The EXIT trap runs when the script ends, however it ends.
  • local keeps a variable inside the function; without it, every variable is global.
  • "$@" is all arguments, each kept whole; $# is how many there are.
  • set -e stops on a failing command, -u on an unset variable, -o pipefail makes a pipeline fail when any part fails. A command tested by if, && or || does not stop the script.
  • exit 1 ends the whole script with that status; Run shows it.