Variable Types and Quoting
While bash variables are technically untyped (everything is a string), understanding how to properly quote and type variables is essential for writing robust scripts.
The Truth About Bash Variables
In bash, all variables are stored as strings:
NUMBER=42 # This is actually the string "42"
TEXT="hello" # This is the string "hello"
# Bash interprets strings as numbers in arithmetic contexts
RESULT=$((NUMBER + 8)) # Works: 50
Declaring Variable Types
Use declare to give variables specific attributes:
# Integer variable (only stores integers)
declare -i count=0
count=5+3 # Arithmetic is automatic: 8
count="hello" # Becomes 0 (invalid integer)
# Read-only variable
declare -r CONSTANT="unchangeable"
# Array variable
declare -a fruits=("apple" "banana")
# Associative array (dictionary)
declare -A colors
colors[sky]="blue"
Why Quoting Matters
Quoting controls how bash interprets special characters and whitespace:
FILE="my file.txt"
# Without quotes - WRONG (tries to cat "my" and "file.txt")
cat $FILE
# With quotes - CORRECT
cat "$FILE"
Three Types of Quoting
1. Double Quotes " "
Variables and commands are expanded, but whitespace is preserved:
NAME="Alice"
echo "Hello, $NAME" # Hello, Alice
echo "Today: $(date)" # Today: Mon Jan 10...
echo "Path: $HOME" # Path: /home/user
2. Single Quotes ' '
Nothing is expanded - everything is literal:
NAME="Alice"
echo 'Hello, $NAME' # Hello, $NAME (literal)
echo 'Today: $(date)' # Today: $(date) (literal)
3. No Quotes
Variables expand, but whitespace causes word splitting:
FILES="file1.txt file2.txt"
# Without quotes - loops twice (word splitting)
for f in $FILES; do echo $f; done
# With quotes - loops once
for f in "$FILES"; do echo $f; done
Exercise: Practice Quoting
Understand the difference between quote types:
Escaping Characters
Use backslash \ to escape special characters:
# Escape dollar sign
echo "Price: \$100" # Price: $100
# Escape double quote inside double quotes
echo "She said \"Hi\"" # She said "Hi"
# Escape newline (continues on next line)
echo "This is a \
long line"
# Common escapes
echo "Tab:\tNewline:\nBackslash:\\"
The $'...' Syntax
For special escape sequences:
# ANSI-C quoting
echo $'Line1\nLine2' # Actual newline
echo $'Tab\there' # Actual tab
echo $'Single\'quote' # Single quote inside
Word Splitting
Understanding word splitting is crucial:
# Word splitting occurs on unquoted variables
TEXT="one two three"
for word in $TEXT; do # Splits into 3 words
echo "Word: $word"
done
# Output:
# Word: one
# Word: two
# Word: three
# Quotes prevent word splitting
for word in "$TEXT"; do # Treated as 1 word
echo "Word: $word"
done
# Output:
# Word: one two three
Glob Expansion
Unquoted variables can trigger glob (wildcard) expansion:
PATTERN="*.txt"
# Without quotes - expands to matching files
echo $PATTERN # file1.txt file2.txt ...
# With quotes - literal asterisk
echo "$PATTERN" # *.txt
Best Practices for Quoting
Always quote variables unless you specifically want word splitting or glob expansion:
# GOOD - always quote
filename="my file.txt"
cp "$filename" "$backup_dir/"
# BAD - will break on spaces
cp $filename $backup_dir/
# Exception: arithmetic context doesn't need quotes
count=$((count + 1))
# Exception: [[ ]] doesn't need quotes (but it doesn't hurt)
if [[ $name == "admin" ]]; then
echo "Welcome admin"
fi
Exercise: Handle Spaces in Filenames
Work with variables containing spaces:
Empty Variables
Handle empty or unset variables carefully:
# This can be dangerous if VAR is empty
rm -rf $VAR/ # If VAR is empty, this becomes: rm -rf /
# Safe: Quote and use default
rm -rf "${VAR:?'VAR must be set'}/"
# Safe: Always quote
if [ -n "$VAR" ]; then
rm -rf "$VAR/"
fi
Here Documents and Here Strings
For multi-line strings:
# Here document - variables are expanded
cat << EOF
Hello $NAME,
Welcome to the system.
Today is $(date).
EOF
# Here document - no expansion (quoted delimiter)
cat << 'EOF'
Hello $NAME,
The variable is not expanded.
EOF
# Here string
grep "pattern" <<< "$variable"
Key Takeaways
- Bash variables are untyped (strings that can be used as numbers)
- Use
declare -ifor integer-only variables - Double quotes
"$VAR"expand variables but preserve whitespace - Single quotes
'$VAR'treat everything literally - Always quote variables to prevent word splitting and glob expansion
- Use
\to escape special characters - Quoting is one of the most important aspects of bash scripting

