Skip to main content

Bash Scripting Cheatsheet

Bash is the most widely used shell scripting language on Linux and macOS. This cheatsheet organizes essential Bash scripting syntax by category — from variable assignment to job control — each with practical examples. Whether you're new to shell programming or need a quick reference, this guide has you covered.

Updated: 2026-07-16·41 commands

Quick Reference

TaskSyntax
Define a variablename='value'
Conditional testif [[ condition ]]; then
Numeric loopfor i in {1..10}; do
File loopwhile read line; do
Define a functionfunction_name() { ... }
Create an arrayarr=(a b c)
Read inputread -p "prompt" var
Command substitutionresult=$(command)
Run in backgroundcommand &

Variables

``bash # Assignment and referencing name='world' # String assignment (no spaces around =) age=42 # Numeric assignment (quotes optional) echo "Hello, $name" # Dollar-sign variable expansion echo "Age is ${age}" # Brace form (for concatenation) echo "${name}_suffix" # Concatenation: world_suffix

# Readonly variables readonly PI=3.14159 # Declare as read-only declare -r GRAVITY=9.8 # Alternative readonly syntax

# Delete a variable unset name # Delete/unset a variable

# Special variables echo "$0" # Script name echo "$1 $2 $3" # Positional parameters echo "$#" # Number of arguments echo "$@" # All arguments as list echo "$?" # Exit code of last command (0=success) echo "$$" # Current process PID echo "$RANDOM" # Random number (0-32767) `

Conditionals

`bash # if / then / else / fi if [[ $age -ge 18 ]]; then echo "Adult" elif [[ $age -ge 60 ]]; then echo "Senior" else echo "Minor" fi

# test command (POSIX compatible) if [ "$name" = "world" ]; then echo "Match" fi

# String comparison [[ "$name" == "world" ]] # Equal (pattern matching) [[ "$name" != "hello" ]] # Not equal [[ -z "$var" ]] # String is empty [[ -n "$var" ]] # String is non-empty

# Numeric comparison [[ $age -eq 42 ]] # Equal [[ $age -ne 0 ]] # Not equal [[ $age -gt 18 ]] # Greater than [[ $age -ge 18 ]] # Greater or equal [[ $age -lt 60 ]] # Less than [[ $age -le 60 ]] # Less or equal

# File tests [[ -f "file.txt" ]] # Is a regular file [[ -d "dir/" ]] # Is a directory [[ -e "path" ]] # Path exists [[ -s "file" ]] # File is non-empty [[ -r "file" ]] # File is readable [[ -w "file" ]] # File is writable [[ -x "file" ]] # File is executable

# Logical operators [[ -n "$var" && $age -gt 0 ]] # AND [[ -z "$var" || $age -eq 0 ]] # OR [[ ! -f "file" ]] # NOT

# case statement case "$os" in linux|Linux) echo "Linux system" ;; darwin|macos) echo "macOS system" ;; *) echo "Unknown system" ;; esac `

Loops

`bash # for loop (numeric range) for i in {1..5}; do echo "Number: $i" done

# for loop (list) for fruit in apple banana orange; do echo "Fruit: $fruit" done

# for loop (C-style) for (( i=0; i

# for loop (globbing) for file in *.sh; do echo "Script: $file" done

# while loop count=1 while [[ $count -le 5 ]]; do echo "Count: $count" ((count++)) done

# while read line by line while IFS= read -r line; do echo "Line: $line" done < input.txt

# until loop until [[ $count -gt 5 ]]; do echo "count = $count" ((count++)) done

# break and continue for i in {1..10}; do [[ $i -eq 3 ]] && continue # Skip 3 [[ $i -eq 8 ]] && break # Stop at 8 echo "i = $i" done # Output: 1 2 4 5 6 7 `

Functions

`bash # Simple function definition greet() { echo "Hello, $1!" }

# Call the function greet "Alice" # Output: Hello, Alice!

# Function with return add() { local a=$1 b=$2 return $((a + b)) } add 3 4 echo "$?" # Output: 7 (return is 0-255 limited)

# Function with result via echo (preferred) multiply() { local a=$1 b=$2 echo $((a * b)) # Use echo to return result } result=$(multiply 6 7) echo "$result" # Output: 42

# local variables myfunc() { local local_var="visible inside function only" global_var="visible everywhere" echo "$local_var" }

# Default parameter values say_hello() { local name=${1:-"World"} # Default: World echo "Hello, $name" }

# Getting all parameters print_args() { for arg in "$@"; do echo "Argument: $arg" done } `

Arrays

`bash # Define arrays fruits=("apple" "banana" "orange") numbers=(1 2 3 4 5)

# Index access echo "${fruits[0]}" # Output: apple echo "${fruits[-1]}" # Output: orange (last element)

# All elements echo "${fruits[@]}" # All elements (space-separated) echo "${fruits[*]}" # All elements (IFS-joined)

# Array length echo "${#fruits[@]}" # Output: 3

# Adding elements fruits+=("grape") # Append fruits[10]="kiwi" # Indexed insert (array auto-expands)

# Deleting elements unset fruits[1] # Delete index 1 (banana) unset fruits # Delete entire array

# Slicing arr=(a b c d e) echo "${arr[@]:1:3}" # Output: b c d (3 elements from index 1) echo "${arr[@]:2}" # From index 2 to end

# Associative arrays (Bash 4+) declare -A user user[name]="Alice" user[age]=30 user[city]="Beijing" echo "${user[name]}" # Output: Alice echo "${!user[@]}" # All keys: name age city `

I/O Operations

`bash # echo output echo "Hello World" # Newline by default echo -n "No newline" # -n suppresses trailing newline echo -e "Tab:\there" # -e enables escape sequences

# printf formatted output printf "Name: %s, Count: %d\\n" "Apple" 5

# read input read -p "Enter name: " name # Prompt for input read -s -p "Password: " pass # -s for silent input (passwords) read -t 5 -p "5s timeout: " var # -t timeout in seconds

# Redirection command > file # stdout to file (overwrite) command >> file # stdout to file (append) command 2> error.log # stderr to file command &> output.log # stdout + stderr combined command < input.txt # file as stdin

# Pipes cmd1 | cmd2 # cmd1 output feeds cmd2 input

# Here Document cat << EOF Multi-line text Variables like $HOME are expanded EOF

# Here String grep "abc" <<< "abcdef" # string as stdin

# tee (split output to screen and file) echo "Log entry" | tee log.txt `

Substitution & Expansion

`bash # Command substitution (two equivalent syntaxes) today=$(date +%Y-%m-%d) # Modern: $(...) — recommended today2=date +%Y-%m-%d # Legacy: backticks

# Arithmetic expansion echo $((5 + 3 * 2)) # Output: 11 echo $(( (a + b) % 10 )) # Using variables num=$((RANDOM % 100 + 1)) # Random 1-100

# let command let "x = 10" let "x += 5"

# Parameter expansion — default values echo "${var:-default}" # If unset/null, use default (var unchanged) echo "${var:=default}" # If unset/null, assign default and return echo "${var:?error msg}" # If unset/null, print error and exit echo "${var:+replacement}" # If set/non-null, use replacement

# Parameter expansion — string operations echo "${#str}" # String length echo "${str:0:3}" # Substring (3 chars from index 0) echo "${str#prefix}" # Remove shortest leading prefix echo "${str##prefix}" # Remove longest leading prefix echo "${str%suffix}" # Remove shortest trailing suffix echo "${str%%suffix}" # Remove longest trailing suffix echo "${str/a/b}" # Replace first match echo "${str//a/b}" # Replace all matches echo "${str^^}" # Uppercase echo "${str,,}" # Lowercase

# Brace expansion echo {a,b,c}.txt # Output: a.txt b.txt c.txt echo {1..5} # Output: 1 2 3 4 5 echo {01..10} # Output: 01 02 ... 10 echo file{1..3}.txt # Output: file1.txt file2.txt file3.txt

# Process substitution diff <(ls dir1) <(ls dir2) # Compare directory listings `

Job Control

`bash # Background execution sleep 100 & # Run in background (returns job ID & PID)

# List background jobs jobs # List all background jobs jobs -l # List jobs with PIDs

# Foreground / Background switching fg %1 # Bring job 1 to foreground bg %1 # Resume suspended job 1 in background

# Suspend and terminate Ctrl+z # Suspend current foreground process Ctrl+c # Terminate current foreground process kill %1 # Terminate job 1 kill -9 1234 # Force kill PID 1234

# nohup (survive terminal close) nohup long-task.sh & # Process continues after terminal exit

# disown (detach from shell) command & disown # Remove from job table (no SIGHUP on exit)

# trap (signal handling) cleanup() { echo "Cleaning up temp files..." rm -rf /tmp/temp_* } trap cleanup EXIT # Run cleanup on script exit trap 'echo "Ctrl+C pressed"' INT # Handle Ctrl+C trap 'echo "Term signal received"' TERM # Handle SIGTERM ``

Variable Ops(4)

CommandLevel
name=value
Variable assignment (no spaces around =)
Basic
readonly / declare -r
Declare a read-only variable
Intermediate
unset
Delete a variable or array element
Basic
$0 $1 $# $@ $?
Special variables — script name, args, count, exit code
Intermediate

Conditionals(6)

CommandLevel
if [[ condition ]]; then ... fi
Conditional statement (double brackets, supports pattern matching)
Basic
[ condition ]
POSIX-compatible test expression
Basic
-eq / -ne / -gt / -lt / -ge / -le
Numeric comparison operators
Basic
-f / -d / -e / -r / -w / -x
File test operators
Intermediate
&& / || / !
Logical AND, OR, NOT
Intermediate
case ... esac
Multi-branch conditional matching
Intermediate

Loops(5)

CommandLevel
for i in {1..5}; do ... done
For loop (numeric range)
Basic
for (( i=0; i<5; i++ )); do ... done
C-style for loop
Intermediate
while [[ condition ]]; do ... done
While conditional loop
Basic
until [[ condition ]]; do ... done
Until conditional loop (executes while condition is false)
Intermediate
break / continue
Exit loop / skip current iteration
Intermediate

Functions(4)

CommandLevel
function_name() { ... }
Define a function
Basic
local var=value
Declare a local variable (visible inside function only)
Intermediate
return
Return from a function (integer exit code 0-255)
Intermediate
${1:-default}
Default value for function parameters
Intermediate

Arrays(4)

CommandLevel
arr=(a b c)
Define an indexed array
Basic
${arr[@]} / ${#arr[@]}
All array elements / array length
Basic
arr+=("item")
Append elements to an array
Intermediate
declare -A map
Define an associative array (Bash 4+)
Expert

I/O(6)

CommandLevel
echo
Output text to stdout
Basic
printf
Formatted output (similar to C printf)
Intermediate
read
Read from stdin
Basic
> / >> / 2> / &> / <
I/O redirection operators
Basic
|
Pipe — send stdout of one command to stdin of another
Basic
cat << EOF
Here Document — multi-line input
Intermediate

Substitution(6)

CommandLevel
$(command)
Command substitution — capture command output into variable
Basic
$(( arithmetic ))
Arithmetic expansion — evaluate integer expression
Basic
${var:-default} / ${var:=default} / ${var:?err}
Parameter expansion — default value, assign default, error exit
Intermediate
${#str} / ${str:0:3} / ${str//a/b} / ${str^^}
Parameter expansion — length, substring, replace, case conversion
Intermediate
{a,b,c} / {1..10}
Brace expansion — generate string sequences
Intermediate
<(command)
Process substitution — pass command output as a file
Expert

Job Control(6)

CommandLevel
command &
Run a command in the background
Basic
jobs
List background jobs in the current shell
Basic
fg / bg
Bring job to foreground / resume in background
Intermediate
kill
Terminate a process or job
Intermediate
nohup
Run a process immune to SIGHUP (survives terminal close)
Intermediate
trap
Trap signals and execute custom handlers
Expert

FAQ

This cheatsheet is compiled from official tool documentation. Last updated: 2026-07-16.