Back to Home
    BashBash Bash 5.xIntermediate

    Bash

    Bash scripting — variables, conditionals, loops, functions, pipes, and common scripting patterns.

    10 min read
    bashshellscriptinglinux

    Script Basics

    2 topics

    Variables & Input

    bash
    #!/usr/bin/env bash
    set -euo pipefail  # Exit on error, unset vars, pipe failures
    
    # Variables
    NAME="Alice"
    echo "Hello, $NAME"
    echo "Hello, ${NAME}!"  # Explicit boundary
    
    # Read user input
    read -p "Enter name: " USER_NAME
    
    # Command substitution
    CURRENT_DIR=$(pwd)
    DATE=$(date +%Y-%m-%d)
    
    # Arithmetic
    COUNT=$((5 + 3))
    echo $((10 % 3))   # 1

    💡 Always start with set -euo pipefail — catches most common bugs

    ⚡ Use ${VAR} when the variable name is followed by non-space characters

    Conditionals

    bash
    # if/elif/else
    if [[ "$ENV" == "production" ]]; then
      echo "prod"
    elif [[ "$ENV" == "staging" ]]; then
      echo "staging"
    else
      echo "dev"
    fi
    
    # File tests
    if [[ -f "$FILE" ]]; then echo "is a file"; fi
    if [[ -d "$DIR" ]]; then echo "is a dir"; fi
    if [[ -z "$VAR" ]]; then echo "empty string"; fi
    if [[ -n "$VAR" ]]; then echo "non-empty"; fi
    
    # Number comparison
    if [[ $COUNT -gt 10 ]]; then echo "more than 10"; fi

    💡 Use [[ ]] (double bracket) not [ ] — it handles empty strings safely

    ⚡ -z checks for empty string, -n for non-empty

    Loops

    1 topic

    for & while

    bash
    # for loop
    for i in {1..5}; do
      echo "Item $i"
    done
    
    # Loop over files
    for file in *.log; do
      echo "Processing $file"
    done
    
    # Loop over array
    FRUITS=("apple" "banana" "cherry")
    for fruit in "${FRUITS[@]}"; do
      echo "$fruit"
    done
    
    # while loop
    COUNT=0
    while [[ $COUNT -lt 5 ]]; do
      echo $COUNT
      ((COUNT++))
    done
    
    # Read file line by line
    while IFS= read -r line; do
      echo "$line"
    done < input.txt

    ⚡ IFS= read -r line is the correct pattern for reading files safely

    Functions

    1 topic

    Defining Functions

    bash
    # Define function
    log() {
      local level="$1"
      local message="$2"
      echo "[$(date +%H:%M:%S)] [$level] $message" >&2
    }
    
    log "INFO" "Starting deployment"
    log "ERROR" "Something went wrong"
    
    # Return values (exit codes)
    file_exists() {
      [[ -f "$1" ]]   # Returns 0 (true) or 1 (false)
    }
    
    if file_exists "config.yml"; then
      echo "Config found"
    fi
    
    # Capture output
    result=$(my_function arg1 arg2)

    💡 Use local for variables inside functions to avoid polluting global scope

    ⚡ Functions return exit codes (0=success), not values — capture with $()

    Pipes & Redirects

    2 topics

    I/O Redirection

    bash
    # Redirect stdout
    command > output.txt      # Overwrite
    command >> output.txt     # Append
    
    # Redirect stderr
    command 2> error.log
    command 2>&1              # stderr to stdout
    command > all.log 2>&1   # Both to file
    
    # Discard all output
    command > /dev/null 2>&1
    
    # Pipe stdout to next command
    ps aux | grep nginx
    cat access.log | grep ' 500 ' | wc -l
    
    # tee — write to file AND pass through to stdout
    command | tee output.log | grep error
    
    # Here string
    grep 'pattern' <<< "$variable"

    💡 2>&1 redirects stderr to wherever stdout currently points — order matters

    ⚡ tee lets you log output while still piping it further down the chain

    xargs & Process Substitution

    bash
    # xargs: build command args from stdin
    find . -name '*.log' | xargs rm
    find . -name '*.txt' | xargs -I{} cp {} /backup/{}
    
    # Parallel execution
    cat urls.txt | xargs -P 4 curl -O
    
    # Process substitution — treat command output as a file
    diff <(sort file1.txt) <(sort file2.txt)
    
    # Safe line-by-line file processing
    while IFS= read -r line; do
      echo "Processing: $line"
    done < input.txt

    ⚡ xargs -P runs in parallel — great for batch file operations like conversions

    💡 Process substitution <() lets you diff command outputs without temp files

    Error Handling

    1 topic

    Exit Codes & Traps

    bash
    #!/usr/bin/env bash
    set -euo pipefail  # Exit on error, unset var, pipe failure
    
    # trap: run cleanup on exit or signal
    TMPDIR=$(mktemp -d)
    trap 'rm -rf "$TMPDIR"' EXIT
    
    # Trap Ctrl+C and TERM
    trap 'echo "Interrupted"; exit 130' INT TERM
    
    # Explicit error check (doesn't require set -e)
    if ! command_that_may_fail; then
      echo "Failed" >&2
      exit 1
    fi
    
    # Default value if command fails
    VALUE=$(get_value) || VALUE="fallback"
    
    # Exit code conventions: 0=success, 1=general error, 127=not found

    💡 trap EXIT is bash's try/finally — guarantees cleanup even on error

    ⚡ Write errors to stderr (>&2) so they don't pollute stdout in pipelines

    Related Articles

    Background reading and deeper explanations for this sheet.

    AI Product Pricing Strategies: How to Monetize for Growth, Margin, and Customer Trust

    Pricing an AI product is not just a finance decision—it shapes adoption, retention, margins, and user trust. In this practical guide, you’ll learn how to choose the right pricing model, align price with value and costs, and avoid common mistakes using real-world examples and implementation frameworks.

    keyword overlap

    FastAPI Interview Questions: Practical Cheat Sheet for Developers

    Preparing for FastAPI interviews can feel overwhelming if you only memorize definitions. This practical cheat sheet helps you answer common FastAPI interview questions with confidence using real-world examples, production-ready patterns, and beginner-friendly explanations with depth.

    keyword overlap

    Handling AI Hallucinations in Real Applications: A Practical Guide for Developers and Product Teams

    Hallucinations are one of the biggest blockers to shipping trustworthy AI features. In this practical guide, you’ll learn how to detect, reduce, and contain hallucinations in production with proven patterns, real-world examples, and implementation-ready code.

    keyword overlap

    Python Stack vs Heap Memory: A Simple, Practical Guide for Developers

    Confused about where Python stores function calls, variables, and real objects? This guide breaks down stack vs heap memory in plain English, with clear examples showing local references on the stack and actual objects on the heap. You’ll learn how this impacts performance, debugging, and writing cleaner Python code.

    keyword overlap