📋 Cheat Sheets

Bash Cheat Sheet — Scripts, Loops, and One-Liners You'll Actually Use


Click any command to expand the explanation and examples.

📝 Variables & Strings

name="value" basics
Assign a variable. No spaces around the = sign — this is the #1 Bash gotcha.
name="Alice"
count=42
path="/usr/local/bin"

Use with $

echo “Hello $name” echo “There are ${count} items”

Use ${var} when the variable is next to other text: ”${name}_backup”

"double quotes" vs 'single quotes' basics
Double quotes expand variables. Single quotes are literal.
name="world"
echo "Hello $name"   # Hello world
echo 'Hello $name'   # Hello $name

Use double quotes for most things

Use single quotes when you want literal $, `, or </pre>

${#string} — string length strings
Get the length of a string.
msg="Hello"
echo ${#msg}   # 5
${string:offset:length} — substring strings
Extract part of a string.
str="Hello World"
echo ${str:0:5}    # Hello
echo ${str:6}      # World
echo ${str: -3}    # rld  (note the space before -)
${string/pattern/replacement} — search & replace strings
Replace text in a string.
file="photo.jpg"
echo ${file/.jpg/.png}     # photo.png

path=“/home/user/docs” echo ${path////\} # \home\user\docs (replace all)

Single / = first match, double // = all matches

${var:-default} — default values strings
Use a default if the variable is empty or unset.
echo ${NAME:-"Anonymous"}   # Anonymous (if NAME is unset)
echo ${PORT:-3000}           # 3000 (if PORT is unset)

:= also assigns the default

echo ${NAME:=“Anonymous”} # sets NAME to Anonymous

🔀 Conditionals

if / elif / else flow
Basic conditional. Use [[ ]] for tests (safer than [ ]).
if [[ $age -gt 18 ]]; then
  echo "Adult"
elif [[ $age -eq 18 ]]; then
  echo "Just turned 18"
else
  echo "Minor"
fi
String comparisons test
Compare strings inside [[ ]].
[[ $a == $b ]]     # equal
[[ $a != $b ]]     # not equal
[[ $a == *.txt ]]  # glob pattern match
[[ $a =~ ^[0-9]+$ ]]  # regex match
[[ -z $a ]]        # string is empty
[[ -n $a ]]        # string is not empty
Number comparisons test
Compare numbers. Use these operators inside [[ ]].
[[ $a -eq $b ]]    # equal
[[ $a -ne $b ]]    # not equal
[[ $a -gt $b ]]    # greater than
[[ $a -ge $b ]]    # greater or equal
[[ $a -lt $b ]]    # less than
[[ $a -le $b ]]    # less or equal

Or use (( )) for arithmetic comparisons

(( a > b )) (( a >= 10 && a <= 20 ))

File tests test
Check if files/directories exist and their properties.
[[ -f file.txt ]]   # file exists (regular file)
[[ -d mydir ]]      # directory exists
[[ -e path ]]       # anything exists (file, dir, link)
[[ -r file ]]       # file is readable
[[ -w file ]]       # file is writable
[[ -x file ]]       # file is executable
[[ -s file ]]       # file is not empty
[[ -L file ]]       # file is a symlink

Example

if [[ -f config.json ]]; then echo “Config found” fi

case statement flow
Pattern matching — cleaner than long if/elif chains.
case $1 in
  start)
    echo "Starting..."
    ;;
  stop)
    echo "Stopping..."
    ;;
  restart)
    echo "Restarting..."
    ;;
  *)
    echo "Usage: $0 {start|stop|restart}"
    exit 1
    ;;
esac

🔁 Loops

for loop loop
Iterate over a list of items.
# Over a list
for fruit in apple banana cherry; do
  echo "$fruit"
done

Over files

for file in *.txt; do echo “Processing $file” done

C-style

for ((i=0; i<10; i++)); do echo “$i” done

Over a range

for i in {1..5}; do echo “$i” done

while loop loop
Loop while a condition is true.
# Count to 5
i=1
while [[ $i -le 5 ]]; do
  echo "$i"
  ((i++))
done

Read a file line by line

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

Infinite loop

while true; do echo “Running…” sleep 1 done

Loop over command output loop
Process the output of a command line by line.
# Process each line
while IFS= read -r line; do
  echo "Found: $line"
done < <(grep -r "TODO" src/)

Or with a for loop (splits on whitespace)

for pid in $(pgrep node); do echo “Node PID: $pid” done

Prefer while read over for — it handles spaces in filenames correctly.

⚙️ Functions

function definition function
Define and call functions.
greet() {
  echo "Hello, $1!"
}

greet “Alice” # Hello, Alice!

With multiple args

add() { echo $(( $1 + $2 )) }

result=$(add 3 5) echo “$result” # 8

$1, $2, etc. are positional arguments. $@ is all arguments. $# is the count.

Return values function
Functions return exit codes (0-255), not values. Use echo + command substitution for values.
# Return a value via echo
get_name() {
  echo "Alice"
}
name=$(get_name)

Return success/failure via return

is_even() { (( $1 % 2 == 0 )) && return 0 || return 1 }

if is_even 4; then echo “Even” fi

🔧 Script Arguments & Special Variables

$0, $1, $@, $#, $? special
Special variables available in every script.
$0     # Script name
$1     # First argument
$2     # Second argument
$@     # All arguments (as separate words)
$*     # All arguments (as one string)
$#     # Number of arguments
$?     # Exit code of last command
$$     # PID of current script
$!     # PID of last background process

Example: ./deploy.sh production —force

$0 = ./deploy.sh

$1 = production

$2 = —force

$# = 2

set -euo pipefail safety
The "strict mode" header every script should have.
#!/bin/bash
set -euo pipefail

-e Exit on any error

-u Error on undefined variables

-o pipefail Catch errors in piped commands

Without this, scripts silently continue after errors — which leads to disasters.

🚀 Common One-Liners

Find and replace in files one-liner
Search and replace text across multiple files.
# macOS (BSD sed)
find . -name "*.js" -exec sed -i '' 's/old/new/g' {} +

Linux (GNU sed)

find . -name “*.js” -exec sed -i ‘s/old/new/g’ {} +

Preview first (no changes)

grep -rn “old” —include=“*.js”

Find large files one-liner
Find files bigger than a certain size.
# Files larger than 100MB
find . -type f -size +100M

With human-readable sizes (Linux)

find . -type f -size +100M -exec ls -lh {} +

Top 10 largest files

du -ah . | sort -rh | head -10

Watch a command one-liner
Re-run a command every N seconds.
# Every 2 seconds
watch -n 2 'docker ps'

macOS (no watch by default)

while true; do clear; docker ps; sleep 2; done

Process CSV / columnar data one-liner
Extract and manipulate columns from text.
# Get second column (space-separated)
awk '{print $2}' file.txt

Get first column (comma-separated)

awk -F’,’ ‘{print $1}’ data.csv

Sum a column

awk ‘{sum += $1} END {print sum}’ numbers.txt

Unique sorted lines

sort file.txt | uniq

Count occurrences

sort file.txt | uniq -c | sort -rn

Parallel execution with xargs one-liner
Run commands in parallel.
# Convert images in parallel (4 at a time)
find . -name "*.png" | xargs -P 4 -I {} convert {} -resize 50% {}

Delete files matching a pattern

find . -name “*.log” -print0 | xargs -0 rm

Run a command for each line of input

cat urls.txt | xargs -I {} curl -s {}