Variable Expansion
Variable expansion is one of Bash's most powerful features. It allows you to provide default values, handle unset variables gracefully, get string lengths, extract substrings, and much more. These techniques make your scripts more robust and handle edge cases elegantly. Once you master variable expansion, you'll write more reliable and concise Bash scripts!
Why Use Braces: ${var}
While $var works in many cases, using braces ${var} is often clearer and sometimes required. Braces help Bash understand where the variable name ends.
Click Run to execute your code
- Concatenation:
${name}_file (not $name_file)- Default values:
${var:-default}- String manipulation:
${var#pattern}- Array access:
${array[0]}
Default Value Expansion
One of the most useful expansion techniques is providing default values when a variable is unset or empty. This prevents errors and makes scripts more user-friendly.
| Syntax | Description | Example |
|---|---|---|
${var:-default} |
Use default if var is unset or empty | ${name:-Guest} โ "Guest" if name is unset |
${var:=default} |
Assign default if var is unset or empty | ${count:=0} โ sets count to 0 if unset |
${var:?error} |
Error with message if var is unset or empty | ${USER:?Not logged in} โ exits if USER unset |
${var:+value} |
Use value if var is set (not default) | ${DEBUG:+yes} โ "yes" if DEBUG is set |
# Example: Using default values
name="" # Empty string
echo "Hello, ${name:-Guest}" # Output: Hello, Guest
# Example: Assigning default
unset port
echo "Port: ${port:=8080}" # Output: Port: 8080, and port is now set to 8080
echo "Port is now: $port" # Output: Port is now: 8080
# Example: Error if required
# USER="${USER:?User must be set}" # Exits with error if USER unset
${var:-default} to provide sensible defaults in scripts. This makes your scripts work even when users don't set optional variables. For example: ${PORT:-8080} uses port 8080 if not specified.
String Length: ${#var}
Get the length of a string using ${#var}. This is useful for validation, formatting, and string manipulation.
text="Hello World"
echo ${#text} # Output: 11
# Practical example: Validate minimum length
password="abc"
if [ ${#password} -lt 8 ]; then
echo "Password too short!"
fi
Substring Expansion: ${var:offset:length}
Extract portions of a string using substring expansion. This is useful for parsing text and extracting specific parts.
text="Hello World"
# Extract substring
echo ${text:0:5} # Output: Hello (from index 0, length 5)
echo ${text:6} # Output: World (from index 6 to end)
echo ${text: -5} # Output: World (last 5 chars, note space before -)
echo ${text:6:3} # Output: Wor (from index 6, length 3)
${text:-5} would use default value syntax, while ${text: -5} gets the last 5 characters.
Practical Examples
Here are real-world scenarios where variable expansion shines:
#!/bin/bash
# Configuration with defaults
PORT="${PORT:-8080}"
HOST="${HOST:-localhost}"
DEBUG="${DEBUG:-false}"
echo "Server: $HOST:$PORT"
[ "$DEBUG" = "true" ] && echo "Debug mode enabled"
# Validate required variable
API_KEY="${API_KEY:?API_KEY environment variable is required}"
echo "API Key: ${API_KEY:0:8}..." # Show only first 8 chars for security
Common Mistakes
1. Confusing := and :- operators
# :- uses default but doesn't assign
unset port
echo "Port: ${port:-8080}" # Uses 8080 but port still unset
echo "port=$port" # Empty
# := assigns default
unset port
echo "Port: ${port:=8080}" # Uses 8080 AND assigns it
echo "port=$port" # 8080
2. Missing space before negative offset
text="Hello World"
# Wrong - interpreted as default value syntax
echo ${text:-5} # Output: Hello World (not last 5 chars!)
# Correct - space before minus
echo ${text: -5} # Output: World
3. Not understanding :+ operator
# :+ is the opposite of :-
# It uses the value if variable IS set (not when unset)
DEBUG="true"
echo ${DEBUG:+enabled} # Output: enabled (DEBUG is set)
unset DEBUG
echo ${DEBUG:+enabled} # Output: (empty, because DEBUG is unset)
Exercise: Use Variable Expansion
Task: Create a script that demonstrates variable expansion techniques!
Requirements:
- Create a variable for username with a default value of "Guest"
- Create a port variable that defaults to 8080 if not set, and assign it
- Create a text variable and display its length
- Extract the first 3 characters and last 3 characters from the text
- Use
${var:?}to ensure a required variable is set
Show Solution
#!/bin/bash
# Variable expansion exercise
# Default value (doesn't assign)
unset username
echo "User: ${username:-Guest}" # Uses default
echo "username is still: '${username:-unset}'" # Still unset
# Assign default value
unset port
echo "Port: ${port:=8080}" # Assigns default
echo "port is now: $port" # Now set
# String length
text="Hello World"
echo "Text: '$text'"
echo "Length: ${#text}"
# Substring extraction
echo "First 3 chars: ${text:0:3}"
echo "Last 3 chars: ${text: -3}"
# Error if required variable unset
required="${REQUIRED:?REQUIRED variable must be set}"
echo "Required: $required"
Summary
- Braces:
${var}is clearer and sometimes required - Default Value:
${var:-default}uses default if unset/empty - Assign Default:
${var:=default}assigns and uses default - Error if Unset:
${var:?error}exits with error if unset - If Set:
${var:+value}uses value if var is set - String Length:
${#var}returns the length - Substring:
${var:offset:length}extracts substring - Negative Offset: Use space before minus:
${var: -5}
What's Next?
Excellent! You've learned powerful variable expansion techniques. Next, we'll explore Environment Variables - special variables that are available to all processes, like PATH, HOME, and USER. Understanding environment variables is crucial for system administration and cross-process communication!
Enjoying these tutorials?