| Expression | Description |
|---|---|
| VAR=value | Assign a value |
| VAR=$(command) | Capture command output (command substitution) |
| $VAR | Read the value |
| ${VAR} | Read with explicit boundary |
| "$VAR" | Read safely with quoting |
| ${VAR:-default} | Use default if VAR is unset or empty |
| ${VAR:=default} | Assign default if VAR is unset or empty |
| ${VAR:+alternate} | Use alternate if VAR is set and not empty |
| ${VAR:?error msg} | Exit with error if VAR is unset or empty |
| ${#VAR} | Length of the value |
| readonly VAR | Make variable read-only |
| export VAR | Make variable available to child processes |
| Expression | Description |
|---|---|
| 'text' | Single quotes: everything is literal |
| "text" | Double quotes: $variables and $(commands) are expanded |
| \$HOME | Backslash escapes a single character |
| Variable | Description |
|---|---|
| $0 | Name of the script |
| $1..$9 | Positional parameters (arguments) |
| ${10} | Positional parameters beyond 9 |
| $# | Number of arguments |
| $@ | All arguments as separate words |
| $* | All arguments as a single string |
| $? | Exit status of the last command |
| $$ | PID of the current shell |
| $! | PID of the last background command |
| $_ | Last argument of the previous command |
| Expression | Description |
|---|---|
| ${VAR#pattern} | Remove shortest match from start |
| ${VAR##pattern} | Remove longest match from start |
| ${VAR%pattern} | Remove shortest match from end |
| ${VAR%%pattern} | Remove longest match from end |
| ${VAR/old/new} | Replace first occurrence |
| ${VAR//old/new} | Replace all occurrences |
| ${VAR:offset} | Substring from offset |
| ${VAR:offset:length} | Substring from offset with length |
| ${VAR^} | Uppercase first character |
| ${VAR^^} | Uppercase all characters |
| ${VAR,} | Lowercase first character |
| ${VAR,,} | Lowercase all characters |
| Operator | Description |
|---|---|
| -f file | True if file exists and is a regular file |
| -d file | True if file exists and is a directory |
| -e file | True if file exists (any type) |
| -r file | True if file is readable |
| -w file | True if file is writable |
| -x file | True if file is executable |
| -s file | True if file exists and is not empty |
| -z string | True if string is empty |
| -n string | True if string is not empty |
| == | String equality (right side is a glob pattern) |
| != | String inequality |
| =~ | Regex match (inside [[ ]]) |
| -eq | Numeric equality |
| -ne | Numeric inequality |
| -lt | Numeric less than |
| -le | Numeric less than or equal |
| -gt | Numeric greater than |
| -ge | Numeric greater than or equal |
| Expression | Description |
|---|---|
| arr=(a b c) | Declare an array |
| arr[0]=value | Set element by index |
| ${arr[0]} | Access element by index |
| "${arr[@]}" | All elements, one word each |
| ${#arr[@]} | Number of elements |
| ${arr[@]:1:2} | Slice: 2 elements starting at index 1 |
| arr+=(d e) | Append elements |
| ${!arr[@]} | All indices |
| unset 'arr[1]' | Remove an element (indices keep a gap) |
| Expression | Description |
|---|---|
| $((a + b)) | Addition |
| $((a - b)) | Subtraction |
| $((a * b)) | Multiplication |
| $((a / b)) | Integer division |
| $((a % b)) | Modulo |
| $((a ** b)) | Exponentiation |
| $((a++)) | Post-increment |
| $((++a)) | Pre-increment |
| ((a += 5)) | Arithmetic assignment |