Bash is superset of sh. Sh is POSIX compliant, bash is not. Bash has many extra features which improve readability and speed of programming. Almost everything what does work on sh would be working on Bash as well, but not the other way.
# At the beginning of the scriptset -xtrap read debug
2.2. Comments
# This is a single-line comment
Multi-line comments are also available using some convention/trick. A herodoc notation string is redirected to a _null command (:). In general, it's recommended to use multiple single-line comments.
: << COMMENTThis is bashmulti-linecommentCOMMENT
2.3. Special variables
$? # Exit code of last command$# # Number of arguments supplied$0 # Current filename (first argument)$1-$9 # Command line arguments (one by one)$@ # Array of arguments$$ # Current PID
2.4. Prologue
#!/usr/bin/env bash # Shebang: run with Bash shell# TL;DRset -ueo pipefail# Exit if undefined variable has been foundset -u# Exit if any exit code of executed functions is not equal zeroset -e# Break pipeline if our script failedset -o pipefail
2.5. Defining variables
NOTE: No spaces around equal sign!
var1=100 # Numbervar2="Number: $var1" # Double quotes == interpolationvar3='Number is stored in $var1' # Single quotes == no interpolationvar4=$(cat test.txt) # Result of commandvar5=("str1" "str2" "str3") # Array of stringsvar6=(1 5 9 43 23 43) # Array of numbersread var7 # Read variable from stdin
2.6. If statement
# If statements (spaces around expression matter)if [ "$var" = "Test value" ]; then commandelif [ "var" = "abcd" ]; then commandelse commandfi# Negationif ! [[ -f $var1 ]] # If file doesn't exist# Number comparisionif [[ $var1 -lt $var2 ]] # If less thanif [[ $var1 -gt $var2 ]] # If greater thanif [[ $var1 -eq $var2 ]] # If equalif [[ $var1 -ne $var2 ]] # If not equal# String comparisionif [[ $var1 = $var2 ]] # If string equalif [[ $var1 != $var2 ]] # If string not equal# Othersif [[ -z $var1 ]] # If null or zero lengthif [[ -n $var1 ]] # If not null and not zero lengthif [[ -d $var1 ]] # If directory existif [[ -f $var1 ]] # If file exist# Compund expressionsif [[ $v1 = $v2 || $v1 != $v3 ]] # Orif [[ $v1 = $v2 && $v1 != $v3 ]] # And
2.7. Loops
# For loopsfor number in {1..12}; do echo "Current number: $number" break continuedonefor file in /bin/* # Iterate over filesfor num in {1..12..2} # {start..end..step}for num in 1 9 4 3 3 # Interate over list of itemsfor item in "${arr[@]}" # Spread array to list of items (above)for (( i=0; i<5; i++ )) # C-like for loopfor name in $(cat names.txt) # Line by line output of a commandfor arg in "$@" # Iterate over arguments# Iterate over lines of variablewhile read -r line; do echo $linedone <<< "$content"# Iterate over lines of filewhile read -r line; do echo $linedone < file.txt
2.8. Functions
Arguments are not named. They are only positional. Same convention as for the
script parameters.
function func1() { echo $1 # Echo 1st argument echo $2 # Echo 2nd argument}func1 "test-argument" 234 # Call a function
2.9. Strings
var='super'echo ${var:0:1} OR ${var::1} => 's' # Get substring of a stringecho ${var:2:2} => 'pe' # ${var:start:n} echo ${var:2} => 'per' # From :2 to endecho ${var:(-2)} => 'e' # Index from endecho ${#var} => 5 # Get length# Case manipulationecho ${str^} => 'Super' # Upper first letterecho ${str^^} => 'SUPER' # Uppercasevar='SUPER'echo ${str,} => 'sUPER' # Lower first letterecho ${str,,} => 'super' # Lowercase# Split into variablesstr='1:2'IFS=: read -r var1 var2 <<< "$str" => var1 == 1, var2 == 2
2.10. Math / arithmetic
$((1 + 1)) # Math expression $((x + y)) # Variables math
2.11. Arrays
arr=("1" "2" "3") # Define arrayarr[3]="4" # Define itemarr+=("5") # Add itemecho ${arr[3]} # Get itemecho ${arr[@]} # Get all items
2.12. Regex
# Check matching and group extractionexp='123(.*)456'if [[ $var1 =~ $exp ]]; then echo $BASH_REMATCH[0] # Entire regex match echo $BASH_REMATCH[1] # First groupfi
2.13. Quick tips
echo $RANDOM # Get random numberdate +%s%N # Get UNIX timestamp (nanoseconds)