Table of Contents#
- What are Shell Variables?
- Declaring and Initializing Variables
- Variable Types in Shell Scripting
- Accessing Variables
- Modifying Variables
- Variable Scope
- Special Variable Operations (Parameter Expansion)
- Environment Variables: Persistence and Scope
- Practical Examples of Shell Scripts with Variables
- Common Pitfalls and Best Practices
- Advanced Topics (Arrays)
- Conclusion
- References
1. What are Shell Variables?#
A shell variable is a named entity that stores data (e.g., text, numbers, or file paths). Variables enable scripts to:
- Store temporary data (e.g., user input, command outputs).
- Make scripts dynamic (e.g., reuse values across commands).
- Configure behavior (e.g., enable debug mode with a flag).
Shell variables are loosely typed—the shell infers the type (string, number, etc.) based on context (e.g., arithmetic operations vs. string concatenation).
2. Declaring and Initializing Variables#
Syntax#
To declare (and initialize) a variable, use:
variable_name=value- No spaces around
=(critical:variable_name = valuethrows an error). - Variable names:
- Contain letters (A-Z, a-z), numbers (0-9), or underscores (
_). - Start with a letter or underscore (not a number).
- Are case-sensitive (e.g.,
MYVAR≠myvar).
- Contain letters (A-Z, a-z), numbers (0-9), or underscores (
Examples#
# String (quotes optional for simple strings, required for spaces)
NAME="John Doe"
# Number
AGE=30
# File path
LOG_FILE="/var/log/app.log"
# Empty variable
EMPTY_VAR=Quoting Variables#
For strings with spaces or special characters, use quotes:
# Correct (preserves spaces)
MESSAGE="Hello, how are you?"
# Incorrect (shell tries to run "how" as a command)
MESSAGE=Hello, how are you?3. Variable Types in Shell Scripting#
Shell variables fall into categories with distinct behaviors:
a. Local Variables#
- Exist only in the current shell session/script (not inherited by child processes).
- Used for temporary data (e.g., intermediate results in a script).
Example:
#!/bin/bash
LOCAL_VAR="I am local"
echo $LOCAL_VAR # Visible in this scriptb. Environment Variables#
- Inherited by child processes (e.g., scripts, commands run from the script).
- Configure system/application behavior (e.g.,
PATH,HOME,USER).
To export a local variable as an environment variable:
MY_VAR="Hello"
export MY_VAR # Now inherited by child processesc. Shell Variables#
- Built-in variables defined by the shell (e.g.,
BASH_VERSION,SHELL). - Some are read-only (e.g.,
$SHELLcannot be modified).
View all shell variables with set:
set # Lists all variables (local, environment, shell)d. Positional Parameters#
- Store command-line arguments passed to a script/function (e.g.,
$1,$2, ...,$9). $*/$@: All positional parameters (see Special Variables).
Example (script: greet.sh):
#!/bin/bash
echo "Hello, $1! You are $2 years old."Run:
./greet.sh Alice 25 # Output: Hello, Alice! You are 25 years old.e. Special Variables#
Predefined variables with unique roles:
$0: Script name (e.g.,greet.sh).$?: Exit status of the last command (0 = success, non-0 = error).$$: Process ID (PID) of the current shell.$!: PID of the last background job.$*/$@: All positional parameters (e.g.,"$@"preserves spaces in arguments).
Example:
#!/bin/bash
echo "Script name: $0"
echo "PID: $$"
sleep 5 & # Run in background
echo "Background job PID: $!"
exit 0
echo "Exit status: $?" # Not executed (after `exit`)4. Accessing Variables#
To use (expand) a variable, prefix its name with $:
Basic Expansion: $variable_name#
NAME="Alice"
echo "Hello, $NAME!" # Output: Hello, Alice!Curly Brace Expansion: ${variable_name}#
- Disambiguate variable names (e.g., when appending text).
- Access array elements (advanced).
Example 1: Disambiguation
NAME="Alice"
echo "Hello, ${NAME}s!" # Output: Hello, Alices! (vs. $NAMEs → error)Example 2: Default Values (advanced)
echo "Value: ${MYVAR:-default}" # Use "default" if MYVAR is unset/empty5. Modifying Variables#
Reassignment#
Change a variable’s value:
COUNT=10
COUNT=20 # Reassign
echo $COUNT # Output: 20Arithmetic Operations#
Use $(( ... )) for integer arithmetic:
NUM1=5
NUM2=3
SUM=$(( NUM1 + NUM2 ))
echo "Sum: $SUM" # Output: 8String Operations#
Concatenation#
FIRST="Hello"
LAST="World"
GREETING="${FIRST} ${LAST}"
echo $GREETING # Output: Hello WorldSubstring Extraction#
Syntax: ${variable:start:length} (index starts at 0):
TEXT="Hello, World"
SUB="${TEXT:7:5}" # Extract "World" (index 7, length 5)
echo $SUB # Output: WorldString Length#
Syntax: ${#variable}:
TEXT="Hello"
LENGTH=${#TEXT} # 5
echo $LENGTH # Output: 56. Variable Scope#
Local vs. Global in Functions#
- Global variables: Visible everywhere in the script (including functions).
- Local variables: Use
localto limit scope to a function (prevents interference).
Example:
#!/bin/bash
GLOBAL="I am global"
my_function() {
local LOCAL="I am local" # Only visible in this function
echo "Inside: $GLOBAL, $LOCAL"
GLOBAL="Modified" # Modifies the global variable
}
my_function
echo "Outside: $GLOBAL, $LOCAL" # $LOCAL is undefined hereOutput:
Inside: I am global, I am local
Outside: Modified,
Exporting to Child Processes#
By default, local variables are not inherited by child processes. Use export to share them:
Parent script (parent.sh):
#!/bin/bash
export MY_VAR="Hello from parent"
./child.shChild script (child.sh):
#!/bin/bash
echo "Child sees: $MY_VAR" # Output: Child sees: Hello from parent7. Special Variable Operations (Parameter Expansion)#
Parameter expansion manipulates variable values. Common use cases:
1. Default Value (if unset/empty)#
${var:-default}: Usedefault(does not setvar).${var:=default}: Usedefault(and setvartodefault).
Example:
echo "${VAR:-fallback}" # Fallback if VAR is unset
echo "${VAR:=fallback}" # Fallback and set VAR to fallback2. Alternate Value (if set/non-empty)#
${var:+alternate}: Usealternateonly ifvaris set/non-empty.
Example:
VAR="hello"
echo "${VAR:+world}" # Output: world (VAR is set)3. Pattern Matching (Remove Prefix/Suffix)#
${var#pattern}: Shortest prefix match.${var##pattern}: Longest prefix match.${var%pattern}: Shortest suffix match.${var%%pattern}: Longest suffix match.
Example (Prefix):
PATH="/usr/bin:/usr/local/bin:/bin"
echo "${PATH#*/}" # Output: usr/bin:/usr/local/bin:/bin
echo "${PATH##*/}" # Output: bin8. Environment Variables: Persistence and Scope#
Session-specific Variables#
Set in the current shell session (lost when the session ends):
export MY_SESSION_VAR="temporary"Persistent Variables#
To make variables persistent (across sessions):
For a Specific User:#
Edit ~/.bashrc (Bash) or ~/.zshrc (Zsh):
export MY_USER_VAR="permanent"Reload: source ~/.bashrc
For All Users:#
Edit /etc/environment (no export needed):
MY_SYSTEM_VAR="permanent for all"Or edit /etc/profile (runs for all users on login):
export MY_SYSTEM_VAR="permanent for all"9. Practical Examples of Shell Scripts with Variables#
Example: Simple Calculator#
#!/bin/bash
echo "Enter first number:"
read NUM1
echo "Enter second number:"
read NUM2
SUM=$(( NUM1 + NUM2 ))
DIFF=$(( NUM1 - NUM2 ))
PROD=$(( NUM1 * NUM2 ))
QUOT=$(( NUM1 / NUM2 ))
echo "Sum: $SUM"
echo "Difference: $DIFF"
echo "Product: $PROD"
echo "Quotient: $QUOT"Run:
./calculator.sh # Input 10 and 5 → Sum: 15, etc.Example: Backup Script#
#!/bin/bash
SOURCE_DIR="/home/user/docs"
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d)
BACKUP_FILE="backup_${DATE}.tar.gz"
mkdir -p $BACKUP_DIR
tar -czf $BACKUP_DIR/$BACKUP_FILE $SOURCE_DIR
echo "Backup created: $BACKUP_DIR/$BACKUP_FILE"This script uses variables to:
- Define paths.
- Generate a timestamped filename.
- Log results.
10. Common Pitfalls and Best Practices#
Pitfalls to Avoid#
-
Spaces around
=:
Wrong:VAR = "value"(shell runsVARas a command).
Correct:VAR="value". -
Unquoted variables with spaces:
Wrong:echo $MESSAGE(may split into multiple arguments).
Correct:echo "$MESSAGE". -
Overwriting built-in variables:
Avoid overwritingPATH,HOME, orPS1.
Best Practices#
- Descriptive names: Use
LOG_FILEinstead oflf. - Quote variables with spaces:
echo "$USER_INPUT". readonlyfor constants:readonly VERSION="1.0" # Prevents accidental changes
11. Advanced Topics (Arrays)#
Declaring Arrays#
# Method 1: Space-separated values
FRUITS=("apple" "banana" "cherry")
# Method 2: Indexed assignment
FRUITS[0]="apple"
FRUITS[1]="banana"Accessing Array Elements#
echo "${FRUITS[0]}" # apple
echo "${FRUITS[@]}" # all elements: apple banana cherry
echo "${#FRUITS[@]}" # length: 3Looping Through Arrays#
for fruit in "${FRUITS[@]}"; do
echo "I like $fruit"
doneConclusion#
Shell variables are the backbone of dynamic and reusable shell scripts. By mastering their types, scope, and manipulation, you can automate complex tasks, configure systems, and build efficient workflows. Use the examples and best practices here to write cleaner, more robust scripts.
References#
-
Bash Manual: Official documentation for Bash variables:
https://www.gnu.org/software/bash/manual/ -
Linux Documentation Project (LDP): Guides on shell scripting:
https://tldp.org/ -
Book: Learning the bash Shell by Cameron Newham and Bill Rosenblatt:
A comprehensive guide to Bash scripting. -
GNU Coreutils Manual: For commands like
export,readonly, andset:
https://www.gnu.org/software/coreutils/manual/