keepcalculator

06 Numbers and Powers

Bash Unbound Variable: Causes and Fixes

Card No. 06·56255 · Updated · Standard formula, shown below

A Bash “unbound variable” error means a script tried to expand a variable that has not been set, usually while the `nounset` option (`set -u`) is enabled. To fix it, identify the expansion named in the error, then either initialize that variable or use a safe default when it may legitimately be absent.

What the error means

Bash variables do not need to be declared before use. Without strict checking, an unset variable expanded as `$name` or `${name}` usually produces an empty string. With `nounset` enabled, Bash treats many such expansions as errors and stops the current command or script, depending on how it is run.

A typical message looks like:

./script.sh: line 4: name: unbound variable

The reported name is the variable Bash could not expand; the line number points to where the expansion occurred. It is not the same as a syntax error, and it does not mean that the variable contains an empty string. “Unset” and “set to an empty value” are distinct states in Bash.

Why nounset is enabled

Scripts often enable stricter checks with:

set -u

The same option can be enabled with `set -o nounset`. It is also common to see `set -euo pipefail`, a combination that requests additional checks for errors, unset variables, and pipeline failures. These options can expose mistakes that might otherwise silently turn into empty arguments or incorrect file paths.

For example, without `nounset`, a misspelled variable might quietly produce an empty value:

set -u
folder=/tmp
printf '%s\n' "$foler"

Here `foler` is probably a typo for `folder`; with `nounset`, Bash reports it rather than continuing. The option is useful for catching mistakes, but it also means scripts must deliberately handle variables that are optional or supplied by callers.

Fix an unset variable

Start with the exact line and variable named in the error. Check spelling, capitalization, and whether the variable is assigned before it is first read. Bash variable names are case-sensitive: `PATH`, `Path`, and `path` are different names.

  1. Correct a typo. Compare the variable in the failing expansion with its assignment and other uses.
  2. Initialize a required variable. Assign it before use, such as name='Ada'.
  3. Check how the script is invoked. A variable expected from the environment may not be exported or may be absent in a different shell, service, scheduled task, or test.
  4. Use a fallback if absence is allowed. Choose an empty string or another default that is valid for the task.
  5. Verify the result safely. Run the script with representative inputs and confirm that a missing value does not produce a misleading command or path.

For a required environment value, it can be clearer to check it explicitly and print a helpful message:

: "${CONFIG_FILE:?Set CONFIG_FILE before running this script}"

If `CONFIG_FILE` is unset or empty, Bash reports the supplied message. Use this form only when an empty value is invalid too.

Safe defaults and parameter expansion

Bash parameter expansion offers concise ways to handle unset values. The punctuation matters:

  • ${value:-default} substitutes `default` when `value` is unset or empty. It does not assign the default to `value`.
  • ${value-default} substitutes the default only when `value` is unset. An explicitly empty value remains empty.
  • ${value:=default} uses the default when the variable is unset or empty, and assigns it to the variable.
  • ${value?message} reports an error if it is unset; ${value:?message} reports an error if it is unset or empty.

For example, this is a common way to allow an optional setting:

output_dir=${OUTPUT_DIR:-./output}

In a script running with `set -u`, the `:-` expansion safely handles an unset `OUTPUT_DIR`. Decide whether an empty string should also trigger the fallback; if it should not, use the form with a single hyphen instead.

Arguments, arrays, and special cases

Unset positional parameters are a frequent cause. A script that reads `$1` assumes its caller supplied a first argument. Validate the argument count before using it:

if (( $# < 1 )); then
  printf 'Usage: %s FILE\n' "$0" >&2
  exit 2
fi
file=$1

Alternatively, use `${1-}` when an absent first argument should be treated as empty, but do not confuse that with validation: an empty argument and a missing argument may have different meanings.

Arrays need care too. Under `nounset`, expanding an array element that does not exist can fail. For an array whose length may be zero, `${array[@]}` is generally the useful expansion for passing its present elements, while code that accesses a particular index should check that the index exists. Associative arrays also need a key to be present before code assumes its value is available.

There are special rules for certain expansions, including some uses of `$@` and `$*`, and behavior can depend on the Bash version and the exact context. Avoid relying on edge cases: test empty arguments and empty arrays in the Bash versions your script supports.

Debugging without hiding the problem

Read the complete error, including the variable name and line number. Then inspect nearby assignments and expansions. If the line is not obvious, search the script for the name and trace which branch is expected to set it.

For additional tracing, Bash can print commands as they are executed:

set -x

Tracing can reveal control flow and values, but it may also print sensitive data such as tokens or passwords. Do not enable it indiscriminately in shared logs. A useful temporary diagnostic is often to report whether a variable is set without printing its contents:

if [[ ${CONFIG_FILE+x} ]]; then
  printf 'CONFIG_FILE is set\n'
else
  printf 'CONFIG_FILE is unset\n'
fi

The `${parameter+x}` form expands to `x` if the variable is set, including when its value is empty, and to nothing if it is unset. This distinction helps diagnose whether the issue is absence or an empty assignment.

Frequently Asked Questions

How do I fix “unbound variable” in Bash?
Find the named variable on the reported line. Correct a typo, assign the variable before use, or use an expansion such as ${name:-default} if a fallback is appropriate.

Does an unbound variable mean the variable is empty?
No. An unset variable has no assigned value; an empty variable is set to an empty string. Use ${name+x} when you need to distinguish those states.

Why does my script work without set -u?
Without `nounset`, an unset variable commonly expands to an empty string. Enabling `set -u` changes that behavior so accidental or unhandled unset-variable expansions are reported.

How do I handle a missing command-line argument?
Check the number of arguments with $# and show a usage message when required arguments are missing. Use a default only when treating the missing argument as an optional value is correct.

Is set -u the same as set -e?
No. `set -u` concerns expansions of unset variables. `set -e` concerns certain commands that return a nonzero status; its behavior has context-dependent exceptions. They are separate options.

Can I turn off nounset for one command?
You can temporarily disable and later re-enable it with set +u and set -u, but that broadens the unchecked section. Prefer a safe parameter expansion or a focused check when possible.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →