name="John"echo $nameecho "$name"echo "${name}!"# Generally quote your variables unless they contain wildcards to expand.wildcard="*.txt"options="iv"cp -$options $wildcard /tmp
String Quotes
name="John"echo "Hi $name" #=> Hi Johnecho 'Hi $name' #=> Hi $name
Shell Execution
echo "I'm in $(pwd)"echo "I'm in `pwd`" # obsolescent
for i in "${!fruits[@]}"; do echo "${fruits[$i]}"done
Slicing
${fruits[@]} # all elements${fruits[@]:1:2} # slice: banana cherry${fruits[@]: -1} # last element: cherry
Length
${#fruits[@]} # number of elements${#fruits[0]} # length of first element
Append
fruits+=("date")
Associative Arrays (Dictionaries)
declare -A capitalcapital[France]="Paris"capital[Japan]="Tokyo"echo "${capital[France]}" #=> Parisfor country in "${!capital[@]}"; do echo "$country: ${capital[$country]}"done
Dictionaries
declare -A useruser=( [name]="John" [email]="john@example.com" [role]="admin")echo "${user[name]}" #=> Johnecho "${!user[@]}" #=> name email role
# Set optionsset -euo pipefailset -x # debug mode (trace)set -n # check syntax without executing# Check optionsset -o # list all optionsset -o pipefail # enable pipefail
History
history # show history!! # last command!$ # last argument!string # last command starting with string!?string # last command containing string^string^new^ # repeat last command, replacing string
# In a script:set -o history # enable history (on by default in interactive)fc -l # list historyfc -s string # re-execute command starting with string
Test / Conditionals
String Tests
[[ -z "$var" ]] # string is empty[[ -n "$var" ]] # string is not empty[[ "$a" == "$b" ]] # equal[[ "$a" != "$b" ]] # not equal[[ "$a" =~ regex ]] # regex match
Numeric Tests
[[ $a -eq $b ]] # equal[[ $a -ne $b ]] # not equal[[ $a -lt $b ]] # less than[[ $a -le $b ]] # less than or equal[[ $a -gt $b ]] # greater than[[ $a -ge $b ]] # greater than or equal
# Files matching pattern:*.txtfile?.log/home/*/data/*.csv# Extended globbing:shopt -s extglobecho !(*.txt) # all files except .txtecho *(foo|bar) # zero or more of foo or barecho +(foo|bar) # one or more of foo or barecho ?(foo|bar) # zero or one of foo or barecho @(foo|bar) # exactly one of foo or bar
User Input
read -p "Enter your name: " nameecho "Hello $name"# Silent input:read -sp "Password: " passwordecho ""# Split into array:read -ra words <<< "one two three"echo "${words[0]}" #=> one
Reading Files
while read -r line; do echo "$line"done < file.txt# With IFS split:while IFS= read -r line; do echo "$line"done < file.txt# Into array:mapfile -t lines < file.txtprintf '%s\n' "${lines[@]}"