__ _______________________ _________._________________________ / \ / \_ _____/\______ \/ _____/| \__ ___/\_ _____/ \ \/\/ /| __)_ | | _/\_____ \ | | | | | __)_ \ / | \ | | \/ \| | | | | \ \__/\ / /_______ / |______ /_______ /|___| |____| /_______ / \/ \/ \/ \/ \/

Bash Quickstart Reference

← Back to quick reference

← Home


Quick reference guide for Bash. Essential syntax, control flow, variables, arrays, and common patterns for shell scripting.


Hello World

#!/bin/bash
echo "Hello, World!"  # The shebang tells the system which interpreter to use

Variables

name="Alice"          # No spaces around =; quotes protect spaces
x=42                  # Numbers are strings until you do math
readonly PI=3.14      # Make variable read-only
unset name            # Delete variable

echo $name            # Access with $ prefix
echo ${name}          # Braces are safer for variable expansion
echo "${name}_suffix" # Use braces when concatenating

Control Flow

If/Else

if [ $x -gt 10 ]; then    # [ ] requires spaces; -gt means "greater than"
    echo "x is big"
else
    echo "x is small"
fi

# Comparison operators: -eq, -ne, -lt, -le, -gt, -ge
# String comparison: =, !=, -z (empty), -n (non-empty)

if [ -f "file.txt" ]; then    # -f checks if file exists
    echo "File exists"
elif [ -d "dir" ]; then       # -d checks if directory exists
    echo "Directory exists"
fi

For Loops

for i in 1 2 3 4 5; do
    echo $i
done

for i in {1..5}; do           # Brace expansion: 1 to 5
    echo $i
done

for file in *.txt; do         # Iterate over files
    echo "Processing $file"
done

for ((i=0; i<5; i++)); do     # C-style for loop
    echo $i
done

While Loops

while [ $x -gt 0 ]; do
    echo $x
    x=$((x - 1))              # Arithmetic expansion
done

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

Case Statement

case $choice in
    "1")
        echo "Option 1"
        ;;
    "2"|"two")
        echo "Option 2"
        ;;
    *)
        echo "Default case"
        ;;
esac

Functions

function greet() {
    local name=$1              # $1 is first argument; local limits scope
    echo "Hello, $name!"
}

greet "Alice"                  # Call function

# Alternative syntax
add() {
    local a=$1
    local b=$2
    return $((a + b))         # Return exit code (0-255)
}

add 2 3
result=$?                     # $? is exit code of last command

Arrays

fruits=("apple" "banana" "cherry")  # Declare array
fruits[3]="date"                     # Add element
echo ${fruits[0]}                    # Access element (apple)
echo ${fruits[@]}                    # All elements
echo ${#fruits[@]}                   # Array length

for fruit in "${fruits[@]}"; do      # Iterate over array
    echo $fruit
done

Strings

text="Hello, World!"
echo ${#text}                  # String length
echo ${text:0:5}               # Substring: start at 0, length 5 ("Hello")
echo ${text/World/Bash}        # Replace first match ("Hello, Bash!")
echo ${text//l/L}              # Replace all matches
echo ${text#Hello, }           # Remove shortest prefix match
echo ${text##Hello, }          # Remove longest prefix match
echo ${text% World!}           # Remove shortest suffix match
echo ${text%% World!}          # Remove longest suffix match

Input / Output

read name                      # Read user input
echo "Enter your name: "
read -p "Name: " name         # Prompt and read in one line
read -s password              # Silent input (for passwords)
read -a array                 # Read into array

echo "Hello"                  # Print to stdout
echo -n "No newline"          # -n suppresses newline
printf "Value: %d\n" 42       # Formatted output

Command Substitution

date=$(date)                  # Capture command output (modern syntax)
date=`date`                   # Backticks (older syntax, less preferred)
files=$(ls *.txt)             # List of files
count=$(wc -l < file.txt)     # Line count

# Process substitution
diff <(sort file1.txt) <(sort file2.txt)

File Operations

# File tests
[ -f "file.txt" ]             # File exists and is regular file
[ -d "dir" ]                  # Directory exists
[ -r "file.txt" ]             # File is readable
[ -w "file.txt" ]             # File is writable
[ -x "file.txt" ]             # File is executable
[ -s "file.txt" ]             # File exists and is not empty

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

# Writing files
echo "content" > file.txt     # Overwrite
echo "content" >> file.txt   # Append

Arithmetic

x=10
y=5

# Arithmetic expansion
result=$((x + y))             # Addition
result=$((x - y))             # Subtraction
result=$((x * y))             # Multiplication
result=$((x / y))             # Division
result=$((x % y))             # Modulo
result=$((x ** 2))            # Exponentiation

# Increment/decrement
((x++))                       # Post-increment
((++x))                       # Pre-increment
((x--))                       # Decrement

Error Handling

set -e                        # Exit on error
set -u                        # Exit on undefined variable
set -o pipefail               # Exit on pipe failure

# Trap errors
trap 'echo "Error occurred"' ERR

# Check command success
if command; then
    echo "Success"
else
    echo "Failed"
fi

# Check exit code
command
if [ $? -eq 0 ]; then
    echo "Success"
fi

Tips

  • Always quote variables to prevent word splitting: "$var" not $var.
  • Use [[ ]] instead of [ ] for more features and fewer surprises (Bash 4+).
  • Use local in functions to avoid polluting global scope.
  • Test file existence with -f (file) or -d (directory) before operations.
  • Use $(( )) for arithmetic; it's safer than expr.
  • Prefer $(command) over backticks for command substitution.
  • Use read -r to prevent backslash interpretation when reading lines.
  • Set IFS= when reading to preserve leading/trailing whitespace.
  • Use set -e at the start of scripts to exit on errors (unless you handle them explicitly).
  • Always start scripts with #!/bin/bash (or appropriate shebang) for portability.
  • Use ${var:-default} to provide default values: name=${1:-"World"}.
  • Check if a command exists before using it:
    if command -v git &> /dev/null; then
        git --version
    fi