The Ultimate Bash Scripting Cheat Sheet: Master Shell Scripting

Introduction

Bash (Bourne Again SHell) is a powerful command-line interpreter and scripting language for Unix-based systems. Bash scripting allows you to automate repetitive tasks, create development workflows, and build powerful system utilities. This cheat sheet covers essential concepts, syntax, and best practices for effective Bash scripting.

Getting Started

Script Structure

#!/bin/bash
# This is a comment
echo "Hello, World!"

Running Scripts

  • Make script executable: chmod +x script.sh
  • Run script: ./script.sh or bash script.sh
  • Debug mode: bash -x script.sh

Shebang Options

  • Basic bash: #!/bin/bash
  • Portable across systems: #!/usr/bin/env bash
  • Strict mode: #!/bin/bash -e (exits on error)

Variables & Data Types

Variable Declaration & Usage

# Assign value (no spaces around =)
name="John"

# Access value ($ prefix)
echo "Hello, $name"
echo "Hello, ${name}"  # Recommended for clarity

# Command substitution
current_dir=$(pwd)
files=`ls`  # Older syntax

# Read-only variable
readonly API_KEY="abc123"

# Unset variable
unset name

Special Variables

VariableDescription
$0Script name
$1$9Positional parameters
$#Number of positional parameters
$@All positional parameters (as separate words)
$*All positional parameters (as a single word)
$?Exit status of previous command
$$Process ID of the current shell
$!Process ID of the most recently backgrounded command
$_Last argument of the previous command

Variable Scope

  • Global: Available throughout the script
  • Local: Available only in the function where declared
local_var="Only visible in this function"

String Operations

String Manipulation

str="Hello World"

# Length
echo ${#str}  # 11

# Substring (position, length)
echo ${str:6:5}  # World

# Replace first occurrence
echo ${str/World/Bash}  # Hello Bash

# Replace all occurrences
echo ${str//l/L}  # HeLLo WorLd

# Remove prefix pattern
echo ${str#Hel}  # lo World

# Remove suffix pattern
echo ${str%orld}  # Hello W

String Comparison

# Equality
if [ "$str1" = "$str2" ]; then
    echo "Strings are equal"
fi

# Inequality
if [ "$str1" != "$str2" ]; then
    echo "Strings are not equal"
fi

# Empty string
if [ -z "$str" ]; then
    echo "String is empty"
fi

# Non-empty string
if [ -n "$str" ]; then
    echo "String is not empty"
fi

Arrays

Array Operations

# Declaration
fruits=("Apple" "Banana" "Cherry")
declare -a numbers=(1 2 3 4 5)

# Access single element
echo ${fruits[1]}  # Banana

# All elements
echo ${fruits[@]}  # Apple Banana Cherry

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

# Slicing
echo ${fruits[@]:1:2}  # Banana Cherry

# Add element
fruits+=("Dragon fruit")

# Delete element
unset fruits[1]

# Associative array (key-value pairs)
declare -A user
user[name]="John"
user[age]=30
echo ${user[name]}  # John

Control Structures

Conditional Statements

# If-else
if [ "$count" -eq 0 ]; then
    echo "Count is zero"
elif [ "$count" -lt 0 ]; then
    echo "Count is negative"
else
    echo "Count is positive"
fi

# Case statement
case "$fruit" in
    "apple")
        echo "It's an apple"
        ;;
    "banana"|"plantain")
        echo "It's a banana or plantain"
        ;;
    *)
        echo "Unknown fruit"
        ;;
esac

Loops

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

# For loop (iterating over items)
for fruit in "${fruits[@]}"; do
    echo "Fruit: $fruit"
done

# While loop
while [ "$count" -gt 0 ]; do
    echo "Count: $count"
    ((count--))
done

# Until loop
until [ "$count" -eq 0 ]; do
    echo "Count: $count"
    ((count--))
done

# Loop control
for i in {1..10}; do
    if [ "$i" -eq 5 ]; then
        continue  # Skip to next iteration
    fi
    if [ "$i" -eq 8 ]; then
        break  # Exit loop
    fi
    echo "Number: $i"
done

Functions

Function Definition & Usage

# Definition
function greet() {
    local name="$1"
    echo "Hello, $name!"
    return 0
}

# Alternative syntax
say_bye() {
    echo "Goodbye, $1!"
}

# Calling functions
greet "John"
say_bye "Jane"

# Capture return value
greet "World"
result=$?
echo "Return value: $result"

Function Parameters

calculate() {
    local a="$1"
    local b="$2"
    local op="$3"
    
    case "$op" in
        "+") echo $(($a + $b)) ;;
        "-") echo $(($a - $b)) ;;
        *) echo "Invalid operator" ;;
    esac
}

result=$(calculate 5 3 "+")
echo "Result: $result"  # Result: 8

File Operations

File Testing

file="example.txt"

# Check if file exists
if [ -e "$file" ]; then
    echo "File exists"
fi

# Common file test operators
[ -f "$file" ]  # Regular file
[ -d "$file" ]  # Directory
[ -r "$file" ]  # Readable
[ -w "$file" ]  # Writable
[ -x "$file" ]  # Executable
[ -s "$file" ]  # Non-zero size

File Reading & Writing

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

# Write to file
echo "New content" > "$file"      # Overwrite
echo "More content" >> "$file"    # Append

# Process file with redirection
cat > "$file" << EOF
Line 1
Line 2
Line 3
EOF

Command Execution & Process Management

Command Substitution

# Store command output
files=$(ls -la)
today=$(date +%Y-%m-%d)

# Use in expressions
if [ "$(whoami)" = "root" ]; then
    echo "Running as root"
fi

Process Management

# Run in background
long_running_command &

# Store PID
pid=$!

# Wait for completion
wait $pid

# Kill process
kill $pid

# Trap signals
trap "echo 'Ctrl+C pressed'; exit 1" SIGINT

Error Handling

Exit Statuses

# Check previous command status
if [ $? -eq 0 ]; then
    echo "Previous command succeeded"
else
    echo "Previous command failed"
fi

# Set exit status
exit 0  # Success
exit 1  # General error

Error Handling Techniques

# Exit on any error
set -e

# Exit on undefined variable
set -u

# Exit if any command in a pipe fails
set -o pipefail

# Combine options
set -euo pipefail

# Restore default behavior
set +e

Input & Output

Standard I/O

# Read user input
echo "Enter your name:"
read name

# Read multiple values
read -p "Enter first and last name: " first last

# Read with timeout
read -t 5 -p "You have 5 seconds: " response

# Silent input (for passwords)
read -s -p "Password: " password

Redirection

# Redirect stdout
echo "Output" > out.txt

# Redirect stderr
command 2> error.log

# Redirect both stdout and stderr
command > out.txt 2>&1

# Redirect both (modern syntax)
command &> out.txt

# Discard output
command > /dev/null

Arithmetic Operations

Basic Calculations

# Using expr (older method)
result=$(expr 5 + 3)

# Using $((...)) syntax
result=$((5 + 3))

# Increment/decrement
((count++))
((count--))

# Compound assignment
((total += value))

Arithmetic Operators

OperatorDescription
+Addition
-Subtraction
*Multiplication
/Division (integer)
%Modulus (remainder)
**Exponentiation
++Increment
--Decrement

Regular Expressions

Pattern Matching

# Check if string matches pattern
if [[ "$string" =~ ^[0-9]+$ ]]; then
    echo "String contains only numbers"
fi

# Extract matched portions
if [[ "$name" =~ ([a-z]+)\.([a-z]+) ]]; then
    echo "First part: ${BASH_REMATCH[1]}"
    echo "Second part: ${BASH_REMATCH[2]}"
fi

Shell Options & Debugging

Shell Options

# Set option
set -o option_name

# Common options
set -o errexit  # Exit on error (same as set -e)
set -o nounset  # Exit on undefined variable (same as set -u)
set -o pipefail # Return status of last failed command in pipe
set -o xtrace   # Print commands before execution (same as set -x)

Debugging Techniques

# Enable tracing for entire script
#!/bin/bash -x

# Enable tracing for specific section
set -x
commands_to_debug
set +x

# Debug function
debug() {
    echo "DEBUG: $@" >&2
}
debug "Current value: $value"

Best Practices

Script Organization

  • Include a shebang line
  • Add descriptive comments
  • Use functions for modular code
  • Include usage information
  • Validate input parameters

Defensive Programming

  • Quote all variables ("$var" not $var)
  • Use set -euo pipefail for safer scripts
  • Check command existence before using
  • Validate input and handle edge cases
  • Use meaningful variable and function names

Performance Optimization

  • Avoid unnecessary subshells
  • Minimize external command calls
  • Use built-in commands when possible
  • Consider alternatives to heavy operations

Resources for Further Learning

Official Documentation

  • Bash Reference Manual: man bash
  • GNU Bash Manual: https://www.gnu.org/software/bash/manual/

Online Resources

  • Bash Hackers Wiki
  • Advanced Bash-Scripting Guide
  • ShellCheck (static analysis tool)
  • Explainshell.com (command explanation)

This cheat sheet covers the fundamentals of Bash scripting. For more advanced topics, refer to the resources listed or explore specialized areas such as process substitution, parameter expansion, and advanced text processing with awk and sed.

Scroll to Top