How to Check if a Variable is Set in Bash
Checking whether variables are set, unset, or empty is crucial for writing robust Bash scripts. Proper variable validation prevents errors, provides meaningful feedback to users, and ensures your scripts behave predictably in different environments.
This guide covers various methods to test variable states, from basic existence checks to advanced parameter expansion techniques.
Basic Variable Existence Check
Use the -v
test operator to check if a variable is set (defined), regardless of its value:
#!/bin/bash
# Set some variables
name="John"
age=30
empty_var=""
# Check if variables are set
if [[ -v name ]]; then
echo "Variable 'name' is set to: '$name'"
else
echo "Variable 'name' is not set"
fi
if [[ -v empty_var ]]; then
echo "Variable 'empty_var' is set but empty: '$empty_var'"
else
echo "Variable 'empty_var' is not set"
fi
if [[ -v undefined_var ]]; then
echo "Variable 'undefined_var' is set"
else
echo "Variable 'undefined_var' is not set"
fi
The -v
operator returns true if the variable is declared, even if it's empty.
Checking for Non-Empty Variables
Use the -n
test operator to check if a variable is set and not empty:
#!/bin/bash
# Different variable states
name="Alice"
empty_string=""
unset_var
# Check for non-empty variables
if [[ -n "$name" ]]; then
echo "Variable 'name' has a value: '$name'"
else
echo "Variable 'name' is empty or unset"
fi
if [[ -n "$empty_string" ]]; then
echo "Variable 'empty_string' has a value"
else
echo "Variable 'empty_string' is empty or unset"
fi
if [[ -n "$unset_var" ]]; then
echo "Variable 'unset_var' has a value"
else
echo "Variable 'unset_var' is empty or unset"
fi
Checking for Empty or Unset Variables
Use the -z
test operator to check if a variable is empty or unset:
#!/bin/bash
validate_required_vars() {
local vars=("$@")
local missing=()
for var_name in "${vars[@]}"; do
# Use nameref to get variable value
if [[ -z "${!var_name}" ]]; then
missing+=("$var_name")
fi
done
if [[ ${#missing[@]} -gt 0 ]]; then
echo "Error: Missing required variables: ${missing[*]}" >&2
return 1
fi
return 0
}
# Example usage
USERNAME="alice"
PASSWORD=""
# API_KEY is not set
if validate_required_vars USERNAME PASSWORD API_KEY; then
echo "All required variables are set"
else
echo "Some required variables are missing"
exit 1
fi
Using Parameter Expansion for Default Values
Bash parameter expansion provides elegant ways to handle unset or empty variables:
#!/bin/bash
# Set default values for unset variables
# ${var:-default} - use default if var is unset or empty
database_host="${DB_HOST:-localhost}"
database_port="${DB_PORT:-5432}"
database_name="${DB_NAME:-myapp}"
echo "Database connection:"
echo " Host: $database_host"
echo " Port: $database_port"
echo " Database: $database_name"
# ${var:=default} - assign default if var is unset or empty
: ${LOG_LEVEL:=INFO}
: ${MAX_RETRIES:=3}
echo "Configuration:"
echo " Log level: $LOG_LEVEL"
echo " Max retries: $MAX_RETRIES"
# ${var:?error_message} - exit with error if var is unset or empty
validate_required() {
: ${API_KEY:?API_KEY environment variable is required}
: ${SECRET_TOKEN:?SECRET_TOKEN environment variable is required}
echo "All required variables are set"
}
# This will exit with error if variables are not set
# validate_required
Comprehensive Variable Checking Function
Here's a robust function that checks various variable states:
#!/bin/bash
check_variable() {
local var_name="$1"
local var_value="${!var_name}"
echo "Checking variable: $var_name"
# Check if variable is declared
if [[ -v "$var_name" ]]; then
echo " ✓ Variable is declared"
# Check if variable is empty
if [[ -z "$var_value" ]]; then
echo " ⚠ Variable is empty"
else
echo " ✓ Variable has value: '$var_value'"
fi
else
echo " ✗ Variable is not declared"
fi
echo
}
# Test different variable states
declared_with_value="Hello World"
declared_empty=""
# undeclared_var is not set
check_variable "declared_with_value"
check_variable "declared_empty"
check_variable "undeclared_var"
Environment Variable Validation
Create a comprehensive environment variable checker:
#!/bin/bash
# Define required and optional environment variables
declare -A required_vars=(
[DATABASE_URL]="Database connection string"
[API_KEY]="API authentication key"
[SECRET_KEY]="Application secret key"
)
declare -A optional_vars=(
[LOG_LEVEL]="Logging level (default: INFO)"
[MAX_WORKERS]="Maximum worker processes (default: 4)"
[TIMEOUT]="Request timeout in seconds (default: 30)"
)
validate_environment() {
local errors=0
echo "Validating environment variables..."
echo
# Check required variables
echo "Required variables:"
for var in "${!required_vars[@]}"; do
if [[ -v "$var" && -n "${!var}" ]]; then
echo " ✓ $var: ${required_vars[$var]}"
else
echo " ✗ $var: ${required_vars[$var]} (MISSING)"
((errors++))
fi
done
echo
# Check optional variables
echo "Optional variables:"
for var in "${!optional_vars[@]}"; do
if [[ -v "$var" && -n "${!var}" ]]; then
echo " ✓ $var: ${!var}"
else
echo " - $var: ${optional_vars[$var]} (not set)"
fi
done
echo
if [[ $errors -gt 0 ]]; then
echo "❌ Environment validation failed: $errors missing variables"
return 1
else
echo "✅ Environment validation passed"
return 0
fi
}
# Run validation
if validate_environment; then
echo "Starting application..."
else
echo "Please set the required environment variables and try again."
exit 1
fi
Array Variable Checking
Check if array variables are set and have elements:
#!/bin/bash
check_array() {
local array_name="$1"
local -n array_ref="$array_name"
echo "Checking array: $array_name"
# Check if array variable is declared
if [[ -v "$array_name" ]]; then
echo " ✓ Array is declared"
# Check if array has elements
if [[ ${#array_ref[@]} -gt 0 ]]; then
echo " ✓ Array has ${#array_ref[@]} elements"
echo " Elements: ${array_ref[*]}"
else
echo " ⚠ Array is empty"
fi
else
echo " ✗ Array is not declared"
fi
echo
}
# Test different array states
populated_array=("apple" "banana" "cherry")
empty_array=()
# undeclared_array is not set
check_array "populated_array"
check_array "empty_array"
check_array "undeclared_array"
Configuration File Variable Loading
Load and validate variables from configuration files:
#!/bin/bash
load_config() {
local config_file="$1"
local required_keys=("$@")
shift # Remove config_file from required_keys
if [[ ! -f "$config_file" ]]; then
echo "Configuration file not found: $config_file" >&2
return 1
fi
# Source the configuration file
source "$config_file"
# Validate required keys
local missing=()
for key in "${required_keys[@]}"; do
if [[ ! -v "$key" || -z "${!key}" ]]; then
missing+=("$key")
fi
done
if [[ ${#missing[@]} -gt 0 ]]; then
echo "Missing required configuration keys: ${missing[*]}" >&2
return 1
fi
echo "Configuration loaded successfully from $config_file"
return 0
}
# Example configuration file validation
if load_config "app.conf" "APP_NAME" "APP_VERSION" "DATABASE_URL"; then
echo "App Name: $APP_NAME"
echo "Version: $APP_VERSION"
echo "Database: $DATABASE_URL"
else
echo "Failed to load configuration"
exit 1
fi
Advanced Variable State Detection
Distinguish between different variable states:
#!/bin/bash
get_variable_state() {
local var_name="$1"
if [[ ! -v "$var_name" ]]; then
echo "UNSET"
elif [[ -z "${!var_name}" ]]; then
echo "EMPTY"
else
echo "SET"
fi
}
# Test function
test_variable_states() {
local unset_var
local empty_var=""
local set_var="value"
echo "Variable states:"
echo " unset_var: $(get_variable_state "unset_var")"
echo " empty_var: $(get_variable_state "empty_var")"
echo " set_var: $(get_variable_state "set_var")"
unset unset_var # Explicitly unset
echo " unset_var (after unset): $(get_variable_state "unset_var")"
}
test_variable_states
Interactive Variable Prompting
Prompt for missing variables interactively:
#!/bin/bash
prompt_for_variable() {
local var_name="$1"
local description="$2"
local default_value="$3"
local is_password="$4"
# Check if variable is already set
if [[ -v "$var_name" && -n "${!var_name}" ]]; then
echo "$var_name is already set"
return 0
fi
# Prompt for value
local prompt="Enter $description"
if [[ -n "$default_value" ]]; then
prompt="$prompt [$default_value]"
fi
prompt="$prompt: "
local value
if [[ "$is_password" == "true" ]]; then
read -s -p "$prompt" value
echo # New line after password input
else
read -p "$prompt" value
fi
# Use default if empty
if [[ -z "$value" && -n "$default_value" ]]; then
value="$default_value"
fi
# Set the variable
declare -g "$var_name"="$value"
}
# Example usage
prompt_for_variable "USERNAME" "username" "" false
prompt_for_variable "PASSWORD" "password" "" true
prompt_for_variable "DATABASE_HOST" "database host" "localhost" false
echo "Configuration complete:"
echo " Username: $USERNAME"
echo " Password: [hidden]"
echo " Database Host: $DATABASE_HOST"
Best Practices
- Use
-v
to check if a variable is declared - Use
-n
to check if a variable has a value - Use
-z
to check if a variable is empty or unset - Always quote variable expansions to handle empty values correctly
- Use parameter expansion for default values and error handling
- Validate required variables early in your scripts
- Provide clear error messages for missing variables
- Consider interactive prompting for missing configuration
- Use arrays for managing multiple related variables
- Document required and optional variables in your scripts
Variable checking is essential for creating robust Bash scripts. By properly validating variable states and providing appropriate defaults or error handling, your scripts will be more reliable and user-friendly.
Found an issue?