Bash Cheatsheet

Control Flow

Use this Bash reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

if / elif / else

if command; then
  echo "command succeeded"
fi

if [ condition ]; then
  echo "true"
elif [ other ]; then
  echo "other"
else
  echo "false"
fi

# One-liner
if [ -f file.txt ]; then echo "exists"; fi

# Preferred modern test with [[ ]]
if [[ $name == "Alice" ]]; then
  echo "hi Alice"
fi

Test Operators — Files

OperatorTrue if
-e filefile exists (any type)
-f filefile exists and is a regular file
-d filefile exists and is a directory
-L filefile is a symbolic link
-r filefile is readable
-w filefile is writable
-x filefile is executable
-s filefile exists and is non-empty
-b fileblock device
-c filecharacter device
-p filenamed pipe (FIFO)
-S filesocket
f1 -nt f2f1 is newer than f2
f1 -ot f2f1 is older than f2
f1 -ef f2f1 and f2 are the same file (hard links)
if [[ -f /etc/passwd ]]; then echo "file exists"; fi
if [[ -d /tmp ]]; then echo "is a directory"; fi
if [[ -x /usr/bin/python3 ]]; then echo "python3 executable"; fi

Test Operators — Strings

OperatorTrue if
-z strstring is empty (zero length)
-n strstring is non-empty
str1 == str2strings are equal (inside [[ ]])
str1 != str2strings are not equal
str1 < str2str1 sorts before str2 (lexicographic)
str1 > str2str1 sorts after str2
str =~ regexstr matches extended regex (inside [[ ]] only)
if [[ -z "$var" ]]; then echo "empty"; fi
if [[ "$a" == "$b" ]]; then echo "equal"; fi
if [[ "$str" =~ ^[0-9]+$ ]]; then echo "all digits"; fi
if [[ "$str" == foo* ]]; then echo "starts with foo"; fi   # glob in [[ ]]

Test Operators — Integers

OperatorMeaning
-eqequal
-nenot equal
-ltless than
-leless than or equal
-gtgreater than
-gegreater than or equal
if [[ $count -gt 0 ]]; then echo "non-zero"; fi
if (( count > 0 )); then echo "non-zero (arithmetic)"; fi  # preferred for numbers

[ ] vs [[ ]] vs (( ))

FormUse forNotes
[ ]POSIX testsrequires quoting; = for string equality
[[ ]]Bash testsno word splitting; glob/regex; ==/!=/=~
(( ))Arithmeticno $ needed; C-style operators; returns 1/0
$(( ))Arithmetic valueexpands to a number
[ "$a" = "$b" ]            # POSIX: note single =
[[ $a == $b ]]             # Bash: safer, no quotes needed for most cases
(( a == b ))               # arithmetic: no $ needed, 0/1 exit status

Compound Conditions

# In [[ ]]
if [[ $a -gt 0 && $b -gt 0 ]]; then echo "both positive"; fi
if [[ $a -gt 0 || $b -gt 0 ]]; then echo "at least one positive"; fi
if [[ ! -f file ]]; then echo "no file"; fi

# In [ ] — use -a and -o (or chain with && ||)
if [ $a -gt 0 ] && [ $b -gt 0 ]; then echo "both"; fi   # preferred
if [ $a -gt 0 -a $b -gt 0 ]; then echo "both"; fi        # avoid (-a is deprecated)

case Statement

case "$var" in
  "start")
    echo "starting"
    ;;
  "stop" | "halt")          # multiple patterns with |
    echo "stopping"
    ;;
  [0-9]*)                   # glob pattern: starts with digit
    echo "number"
    ;;
  *.txt)                    # glob: ends in .txt
    echo "text file"
    ;;
  *)                        # default catch-all
    echo "unknown"
    ;;
esac

# Fall-through (Bash 4+): ;& continues to next block, ;;& tests next pattern
case "$x" in
  a) echo "a" ;&            # falls through to b
  b) echo "b" ;;
  c*) echo "starts c" ;;&  # continues testing
  c[0-9]) echo "c+digit" ;;
esac

select — Interactive Menu

select option in "Start" "Stop" "Quit"; do
  case $option in
    "Start") echo "Starting..." ;;
    "Stop")  echo "Stopping..." ;;
    "Quit")  break ;;
    *)       echo "Invalid choice" ;;
  esac
done
# select loops forever; use break or Ctrl+D to exit
# PS3 controls the prompt (default is "#? ")
PS3="Choose: "

Short-circuit Evaluation

# && is "and-then" — right side runs only if left side succeeds
mkdir -p /tmp/foo && echo "created"

# || is "or-else" — right side runs only if left side fails
cd /nonexistent || { echo "error"; exit 1; }

# Common patterns
[[ -f file ]] && cat file
[[ -z "$1" ]] && { echo "usage: $0 <arg>"; exit 1; }

# Ternary-style
result=$(( a > b ? a : b ))   # arithmetic ternary

Null Coalescing Patterns

# Use default if unset
name=${1:-"world"}
echo "Hello, $name"

# Assign default if unset
: ${PORT:=8080}
echo "Port: $PORT"

# Error if required variable missing
: ${API_KEY:?"API_KEY must be set"}