Bash provides powerful mechanisms for assigning default values to variables, simplifying script logic and making code more robust. This tutorial explores these techniques, allowing you to handle unset or null variables gracefully.
Understanding Variable States
Before diving into the techniques, it’s important to understand the possible states of a Bash variable:
- Set: The variable has been assigned a value.
- Unset: The variable has never been assigned a value.
- Null: The variable has been assigned an empty string (
""
).
Many scripts rely on variables having specific values. When a variable is unset or null, attempting to use it directly can lead to errors or unexpected behavior. The techniques described below provide ways to ensure a variable always has a meaningful value.
Assigning Default Values with Parameter Expansion
Bash offers parameter expansion capabilities that allow you to assign default values directly within variable assignments. This is the most concise and recommended approach.
1. Using ${VARIABLE:-default}
This form checks if VARIABLE
is unset or null. If either condition is true, the variable will be expanded to default
. Importantly, the value of VARIABLE
itself does not change.
VARIABLE=""
FOO="${VARIABLE:-'my_default'}"
echo $FOO # Output: my_default
echo $VARIABLE # Output: "" (original value unchanged)
2. Using ${VARIABLE:=default}
This form also checks if VARIABLE
is unset or null, but with a crucial difference: if the variable is unset or null, it sets the variable VARIABLE
to default
and expands to default
.
VARIABLE=""
FOO="${VARIABLE:='my_default'}"
echo $FOO # Output: my_default
echo $VARIABLE # Output: my_default (value has been changed)
3. Using ${VARIABLE:+word}
This form checks if VARIABLE
is set (i.e., not unset or null). If it is set, the variable expands to word
. Otherwise, it expands to nothing. This is useful for providing alternative values only when a variable already has a value.
VARIABLE="some_value"
FOO="${VARIABLE:+another_value}"
echo $FOO # Output: another_value
VARIABLE=""
FOO="${VARIABLE:+another_value}"
echo $FOO # Output: (empty string)
4. Using ${VARIABLE:?message}
This form is used for error checking. If VARIABLE
is unset or null, it will print the message
to standard error and exit the script. This is useful for ensuring that critical variables are always set before the script continues.
VARIABLE=""
FOO="${VARIABLE:?VARIABLE must be set}"
# This will print an error message and exit the script
Using Default Values from Other Variables
You can also use the value of another variable as the default value. This is useful for configuration settings or shared defaults.
DEFAULT_VALUE="fallback_value"
VARIABLE=""
FOO="${VARIABLE:-$DEFAULT_VALUE}"
echo $FOO # Output: fallback_value
Practical Example: Command-Line Arguments
A common use case is providing default values for command-line arguments:
DEFAULT_DIR="/home/user/data"
INPUT_DIR="${1:-$DEFAULT_DIR}" # Use first argument or default directory
echo "Processing data in: $INPUT_DIR"
If the script is run without any arguments, $INPUT_DIR
will be set to /home/user/data
. If an argument is provided (e.g., ./script.sh /tmp
), $INPUT_DIR
will be set to /tmp
.
Best Practices
- Clarity: Choose the parameter expansion form that best reflects your intent.
- Error Handling: Use
${VARIABLE:?message}
for critical variables to prevent unexpected behavior. - Quoting: Use double quotes around the entire parameter expansion to prevent word splitting and globbing, especially when the default value contains spaces or special characters.
- Readability: While concise, complex parameter expansions can be difficult to read. Consider breaking them down into multiple lines for improved clarity if necessary.