bash: NAME: unbound variable
verified onenvironmentlocal · linux 6.18.44-fc-v140 x64 · GNU bash 5.2.21updated
- tool
- Bash
- exit code
- 1
- versions
- bash 4.x, bash 5.x
- os
- linux, macos, windows
NAME: unbound variable is printed by bash when the nounset option (set -u) is on and the script expands a variable that has never been set. bash stops the script instead of silently using an empty string. Give optional variables an explicit default with ${NAME:-default}, or check that required arguments were passed before using them.
Reproduce it
cat > greet.sh <<'EOF'
set -u
echo "start"
echo "hello ${NAME}"
echo "never printed"
EOF
bash greet.sh
echo "exit status: $?"Output
start greet.sh: line 3: NAME: unbound variable exit status: 1
The message names the script, the line and the variable, and the script stops with status 1. A missing positional parameter fails the same way:
cat > first.sh <<'EOF'
set -u
echo "first argument: $1"
EOF
bash first.sh
echo "exit status: $?"Output
first.sh: line 2: $1: unbound variable exit status: 1
Fixes
cat > greet.sh <<'EOF'
set -u
echo "hello ${NAME:-world}"
echo "optional: [${OPTIONAL:-}]"
if [[ -v NAME ]]; then echo "NAME is set"; else echo "NAME is not set"; fi
EOF
bash greet.sh
NAME=ada bash greet.shOutput
hello world optional: [] NAME is not set hello ada optional: [] NAME is set
| Expansion | When NAME is unset | Use for |
|---|---|---|
| ${NAME:-default} | expands to default | optional settings |
| ${NAME:-} | expands to an empty string | optional values that may be empty |
| ${NAME:=default} | assigns default, then expands it | set once, reuse later |
| ${NAME:?message} | prints message and exits | required values with a clear error |
| ${NAME+x} | empty if unset, x if set | testing whether NAME is set |
Required arguments
cat > copy.sh <<'EOF'
set -u
src=${1:?usage: copy.sh SOURCE}
echo "copying $src"
EOF
bash copy.sh
echo "exit status: $?"Output
copy.sh: line 2: 1: usage: copy.sh SOURCE exit status: 1
${1:?message} turns the generic error into a usage message and still exits with a non-zero status. "$@" never triggers the error, even with no arguments.
Sources
Related pages
flags · bashset -euo pipefail: what each flag does in bashset -e exits on the first failing command, -u treats unset variables as errors and -o pipefail makes a pipeline fail if any command in it fails. Examples.codes · bashBash exit codes: 0, 1, 2, 126, 127, 128+n and 255What bash exit codes mean: 0 success, 1 general error, 2 misuse of builtins, 126 not executable, 127 not found, 128+n killed by signal n, and how to read $?.errors · bashbash: command not found (exit status 127)bash prints "command not found" and exits with status 127 when a command is not in PATH, not installed or misspelled. Check with command -v and fix PATH.errors · bashbash: [: integer expression expectedBash prints this when [ ] or test compares a value with -eq, -lt or -gt and it is not an integer. Quote the variable, validate the input or compare strings.