Variables & Quoting Cheat Sheet¶
Quoting rules and variable types — the foundation of bug-free bash scripts.
Variable Assignment¶
No spaces around =
name = "hello" is a syntax error — bash sees name as a command.
Quoting Types¶
| Quote | Effect |
|---|---|
"..." |
Allows $var and $(cmd) expansion; prevents glob and word-splitting |
'...' |
Completely literal — no expansion of any kind |
| No quotes | Word-splitting and glob expansion happen |
name="Ada Lovelace"
echo $name # Ada Lovelace (lucky — splits into two words if passed to cmd)
echo "$name" # Ada Lovelace (correct — one argument)
echo '$name' # $name (literal)
Rule: Quote every variable reference: "$var", "$@", "${arr[@]}".
Special Variables¶
| Variable | Meaning |
|---|---|
$0 |
Script name |
$1 … $9 |
Positional arguments |
${10} |
Arguments beyond 9 (braces required) |
$# |
Number of arguments |
$@ |
All arguments (separately quoted as "$@") |
$* |
All arguments as one string ("$*") |
$? |
Exit status of last command |
$$ |
PID of current shell |
$! |
PID of last background process |
$_ |
Last argument of previous command |
$- |
Current shell option flags |
Environment Variables¶
export VAR="value" # make available to child processes
printenv # list all env vars
env # list all env vars
unset VAR # remove a variable
Common environment variables:
| Variable | Typical value |
|---|---|
$HOME |
/home/user |
$PATH |
/usr/local/bin:/usr/bin:/bin |
$USER |
user |
$SHELL |
/bin/bash |
$PWD |
Current directory |
$EDITOR |
vim |
$LANG |
en_US.UTF-8 |
$TERM |
xterm-256color |
$@ vs $*¶
args() { for a in "$@"; do echo "[$a]"; done; }
args "hello world" "foo" # "$@": ["hello world"] ["foo"]
# vs
args2() { for a in "$*"; do echo "[$a]"; done; }
args2 "hello world" "foo" # "$*": ["hello world foo"]
Always use "$@" when passing arguments to another command.
Command Substitution¶
today=$(date +%Y-%m-%d) # modern syntax — use this
today=`date +%Y-%m-%d` # old backtick syntax — avoid
count=$(ls | wc -l)
Arithmetic¶
result=$(( 5 + 3 )) # arithmetic expansion
(( count++ )) # increment (exit code 0 if non-zero result)
(( count += 5 )) # compound assignment
let "x = 5 * 3" # older syntax, avoid
(( 0 )) returns exit code 1
(( count-- )) when count is 1 sets it to 0, which returns exit code 1 — and with set -e, this exits the script. Use (( count-- )) || true to guard against this.
Variable Scoping¶
GLOBAL="global"
my_func() {
local LOCAL="local" # visible only in this function
GLOBAL="modified" # modifies the global
}
my_func
echo "$GLOBAL" # modified
echo "$LOCAL" # empty — not visible outside function
readonly Variables¶
readonly MAX=100
readonly -a COLORS=("red" "green" "blue")
MAX=200 # error: cannot assign to readonly variable
Related: bash-parameter-expansion