Tired of writing repetitive, hard-coded values in your bash scripts? Variables are the key to creating dynamic, maintainable shell scripts that can adapt to different situations and user inputs.
๐ฏ What You'll Learn: In this comprehensive guide, you'll discover:
- How to declare and assign values to bash variables
- Variable naming conventions and best practices
- Different ways to use variables in your scripts
๐ Understanding Bash Variables
Variables in bash are containers that store data values. They make your scripts flexible, reusable, and easier to maintain. Instead of repeating the same value throughout your script, you can store it in a variable and reference it whenever needed.
Prerequisites
Before we dive in, make sure you have:
- Completed the Creating Your First Bash Script tutorial
- Basic understanding of bash script execution
- Access to a Linux terminal
๐ Creating Your First Variable Script
Let's start by creating a simple script that demonstrates variable usage:
touch using_variables.sh
chmod +x using_variables.sh
โ Pro Tip: Notice how we're making the script executable right after creating it. This saves time and prevents the common "Permission denied" error.
Now let's add some content to our script:
#!/bin/bash
NAME="Alice"
echo "Hello $NAME!"
When we execute this script:
$ ./using_variables.sh
Hello Alice!
๐๏ธ Variable Declaration and Assignment
Basic Variable Assignment
In bash, variables are assigned without spaces around the equals sign:
#!/bin/bash
# Correct way to assign variables
NAME="Alice"
AGE=25
CITY="New York"
# Using the variables
echo "Name: $NAME"
echo "Age: $AGE"
echo "City: $CITY"
โ Common Mistakes
# Wrong - spaces around =
NAME = "Alice"
# Wrong - using $ in assignment
$NAME = "Alice"
# Wrong - inconsistent quotes
NAME = 'Alice"
โ Correct Syntax
# Right - no spaces
NAME="Alice"
# Right - no $ in assignment
NAME="Alice"
# Right - consistent quotes
NAME="Alice"
Variable Naming Conventions
๐ Best Practices for Variable Names:
- Use UPPERCASE for environment variables and constants
- Use lowercase for local script variables
- Use underscores to separate words
- Start with a letter or underscore, not a number
- Avoid special characters except underscores
#!/bin/bash
# Constants and environment-like variables
DATABASE_URL="localhost:5432"
MAX_RETRIES=3
# Local script variables
user_name="bob"
file_count=10
temp_directory="/tmp/myapp"
echo "Database: $DATABASE_URL"
echo "User: $user_name"
echo "Files: $file_count"
๐ Modifying Variables Dynamically
Let's see how we can change variable values during script execution:
#!/bin/bash
# Initial assignment
NAME="Alice"
echo "Hello $NAME!"
# Changing the variable
NAME="Bob"
echo "Hello $NAME!"
# You can also assign based on other variables
GREETING="Hello"
FULL_MESSAGE="$GREETING $NAME!"
echo "$FULL_MESSAGE"
Output:
$ ./dynamic-variables.sh
Hello Alice!
Hello Bob!
Hello Bob!
This demonstrates the dynamic nature of variables - you can modify them at any point in your script, just like we did in our terminal session.
๐ฏ Variable Substitution Methods
Bash offers several ways to use variables in your scripts:
Basic Variable Substitution
#!/bin/bash
NAME="Alice"
AGE=30
# Method 1: Direct substitution
echo "Hello $NAME"
# Method 2: Braced substitution (recommended)
echo "Hello ${NAME}"
# Method 3: When concatenating
echo "Hello ${NAME}123" # Clear separation
echo "Hello $NAME123" # This would look for variable NAME123!
โ ๏ธ Important: Use braces ${VAR}
when concatenating variables with other text to avoid confusion about where the variable name ends.
Advanced Substitution Techniques
#!/bin/bash
FILENAME="document.txt"
# Get the length of a variable
echo "Filename length: ${#FILENAME}"
# Substring extraction
echo "First 3 characters: ${FILENAME:0:3}"
echo "Extension: ${FILENAME: -3}"
# Default values
echo "User: ${USER_NAME:-'Anonymous'}" # Use 'Anonymous' if USER_NAME is unset
# Case conversion (Bash 4+)
GREETING="hello world"
echo "Uppercase: ${GREETING^^}"
echo "Lowercase: ${GREETING,,}"
๐ ๏ธ Practical Examples
Example 1: Configuration Script
#!/bin/bash
# Configuration variables
SERVER_NAME="web-server-01"
PORT=8080
LOG_LEVEL="INFO"
BACKUP_DIR="/var/backups"
# Display configuration
echo "=== Server Configuration ==="
echo "Server Name: $SERVER_NAME"
echo "Port: $PORT"
echo "Log Level: $LOG_LEVEL"
echo "Backup Directory: $BACKUP_DIR"
# Create backup directory if it doesn't exist
echo "Creating backup directory: $BACKUP_DIR"
mkdir -p "$BACKUP_DIR"
# Generate a log file name
LOG_FILE="${BACKUP_DIR}/${SERVER_NAME}_$(date +%Y%m%d).log"
echo "Log file: $LOG_FILE"
Example 2: File Processing Script
#!/bin/bash
# File processing variables
INPUT_DIR="/home/user/documents"
OUTPUT_DIR="/home/user/processed"
FILE_EXTENSION=".txt"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Create output directory
mkdir -p "$OUTPUT_DIR"
echo "Processing files from: $INPUT_DIR"
echo "Output directory: $OUTPUT_DIR"
echo "Looking for files with extension: $FILE_EXTENSION"
echo "Process timestamp: $TIMESTAMP"
# Example of using variables in a loop context
COUNTER=0
for file in "${INPUT_DIR}"/*"${FILE_EXTENSION}"; do
if [[ -f "$file" ]]; then
COUNTER=$((COUNTER + 1))
echo "Processing file $COUNTER: $(basename "$file")"
fi
done
echo "Processed $COUNTER files"
๐ Variable Scope and Environment
Local vs Environment Variables
#!/bin/bash
# Local variable (only available in this script)
LOCAL_VAR="I'm local"
# Environment variable (available to child processes)
export GLOBAL_VAR="I'm global"
# Display current shell's variables
echo "Local: $LOCAL_VAR"
echo "Global: $GLOBAL_VAR"
# Call another script or command that inherits GLOBAL_VAR
# The called process won't see LOCAL_VAR but will see GLOBAL_VAR
Reading System Environment Variables
#!/bin/bash
# Using built-in environment variables
echo "Current user: $USER"
echo "Home directory: $HOME"
echo "Current directory: $PWD"
echo "Shell: $SHELL"
echo "Path: $PATH"
# Using variables in conditions
if [[ "$USER" == "root" ]]; then
echo "Running as root user"
else
echo "Running as regular user: $USER"
fi
๐จ Common Pitfalls and Solutions
Spaces in Variable Assignment
Problem: NAME = "Alice"
gives "command not found"
Cause: Bash interprets this as running a command called NAME
Solution: Remove spaces: NAME="Alice"
# Wrong
NAME = "Alice" # Error: command not found
# Correct
NAME="Alice" # Works perfectly
Using $ in Assignment
Problem: $NAME="Alice"
doesn't work as expected
Cause: The $
is only for accessing variables, not assigning them
Solution: Don't use $
when assigning: NAME="Alice"
# Wrong
$NAME="Alice" # Syntax error
# Correct
NAME="Alice" # Assignment
echo "$NAME" # Access with $
Unquoted Variables with Spaces
Problem: Variables containing spaces cause word splitting Cause: Unquoted variables are split on whitespace Solution: Always quote variables when using them
FILE_NAME="my document.txt"
# Wrong - will be treated as multiple arguments
rm $FILE_NAME
# Correct - treated as single argument
rm "$FILE_NAME"
๐งช Testing Your Understanding
Create a script that demonstrates variable usage:
#!/bin/bash
# Personal information
FIRST_NAME="John"
LAST_NAME="Doe"
FULL_NAME="$FIRST_NAME $LAST_NAME"
# System information
CURRENT_DATE=$(date +%Y-%m-%d)
HOSTNAME=$(hostname)
# Display information
echo "=== Personal Information ==="
echo "First Name: $FIRST_NAME"
echo "Last Name: $LAST_NAME"
echo "Full Name: $FULL_NAME"
echo ""
echo "=== System Information ==="
echo "Date: $CURRENT_DATE"
echo "Hostname: $HOSTNAME"
echo "User: $USER"
# Demonstrate variable modification
echo ""
echo "=== Variable Modification ==="
COUNTER=1
echo "Counter starts at: $COUNTER"
COUNTER=$((COUNTER + 1))
echo "Counter after increment: $COUNTER"
COUNTER=$((COUNTER * 10))
echo "Counter after multiplication: $COUNTER"
๐ฏ Key Takeaways
โ Remember These Points
- No Spaces in Assignment: Always use
VAR="value"
, neverVAR = "value"
- Quote Your Variables: Use
"$VAR"
to prevent word splitting and preserve spaces - Use Braces for Clarity: Prefer
${VAR}
when concatenating with other text - Naming Convention: UPPERCASE for constants, lowercase for local variables
- Environment vs Local: Use
export
to make variables available to child processes
๐ Further Reading
Official Resources
๐ Excellent Work! You now understand how to use variables to make your bash scripts dynamic and maintainable. Variables are the foundation of more advanced scripting concepts you'll learn next.
What scripts are you planning to enhance with variables? Share your ideas in the comments!
๐ฌ Discussion
I'd love to hear about your variable usage experience:
- What's the most useful variable-based script you've created?
- Have you encountered any tricky variable scoping issues?
- What variable naming convention do you prefer and why?
- Any specific variable manipulation techniques you'd like me to cover?
Connect with me:
- ๐ GitHub - See variable examples and templates
- ๐ง Contact - Scripting questions and discussions