Bash Scripting Cheat Sheet

Cheet says: Automate all the things!

Script Header


#!/bin/bash
set -euo pipefail    # Exit on error, undefined, pipe fail

Or more explicit:

set -e # Exit on error set -u # Error on undefined variable set -o pipefail # Pipe fails if any command fails

Variables


name="world"
echo "Hello $name"
echo "Hello ${name}!"

Default values

echo ${var:-default} # Use default if unset echo ${var:=default} # Set default if unset echo ${var:+alternate} # Use alternate if set echo ${var:?error msg} # Error if unset

String operations

${#var} # Length ${var^^} # Uppercase ${var,,} # Lowercase ${var:0:5} # Substring (start:length) ${var/old/new} # Replace first ${var//old/new} # Replace all

Conditionals


If statement

if [[ $x -eq 1 ]]; then echo "one" elif [[ $x -eq 2 ]]; then echo "two" else echo "other" fi

Comparisons

[[ $a == $b ]] # String equal [[ $a != $b ]] # String not equal [[ $a -eq $b ]] # Integer equal [[ $a -ne $b ]] # Integer not equal [[ $a -lt $b ]] # Less than [[ $a -gt $b ]] # Greater than [[ -z $a ]] # Is empty [[ -n $a ]] # Is not empty

File tests

[[ -e file ]] # Exists [[ -f file ]] # Is file [[ -d dir ]] # Is directory [[ -r file ]] # Is readable [[ -w file ]] # Is writable [[ -x file ]] # Is executable

Logical

[[ $a && $b ]] # AND [[ $a || $b ]] # OR [[ ! $a ]] # NOT

Loops


For loop

for i in 1 2 3; do echo $i done for i in {1..10}; do echo $i done for file in *.txt; do echo "$file" done

While loop

while [[ $count -lt 10 ]]; do ((count++)) done

Read file line by line

while IFS= read -r line; do echo "$line" done < file.txt

Infinite loop

while true; do sleep 1 done

Functions


my_function() {
    local name=$1    # Local variable
    echo "Hello $name"
    return 0
}

Call it

my_function "world"

Get return value

result=$(my_function "test")

Arrays


Define

arr=(one two three) arr[0]="first"

Access

echo ${arr[0]} # First element echo ${arr[@]} # All elements echo ${#arr[@]} # Length echo ${!arr[@]} # All indices

Iterate

for item in "${arr[@]}"; do echo "$item" done

Add element

arr+=("four")

Input/Output


Read input

read -p "Enter name: " name read -s -p "Password: " pass # Silent

Here document

cat <Redirectcmd > file # Stdout to file cmd >> file # Append cmd 2> file # Stderr to file cmd &> file # Both to file cmd 2>&1 # Stderr to stdout

Useful Patterns


Check command exists

if command -v git &>/dev/null; then echo "git installed" fi

Parse arguments

while [[ $# -gt 0 ]]; do case $1 in -h|--help) show_help; exit 0 ;; -v|--verbose) VERBOSE=1 ;; *) echo "Unknown: $1"; exit 1 ;; esac shift done

Trap signals

cleanup() { rm -f /tmp/lockfile; } trap cleanup EXIT

Progress dots

for i in {1..10}; do echo -n "." sleep 0.1 done echo " done!"

Parallel execution

for task in task1 task2 task3; do run_task "$task" & done wait # Wait for all

Best Practices


Quote your variables

echo "$var" # Good echo $var # Bad - word splitting

Use [[ ]] not [ ]

[[ $a == $b ]] # Good [ $a == $b ] # Bad - less safe

Use $() not backticks

result=$(command) # Good result=`command` # Bad - hard to nest

Check errors

if ! command; then echo "Failed" exit 1 fi