Bash Cheat Sheet — Essential Commands & Scripting

BeginnerCheat Sheet20 min7 min read10 Jan 2025Bash

A comprehensive Bash reference covering navigation, file ops, pipes, redirects, text processing, loops, functions, and useful one-liners.

What you'll learn

  • Navigate the file system efficiently
  • Manipulate files and directories
  • Use pipes, redirects, and process substitution
  • Write basic scripts with variables, loops, and conditionals
pwd                  # Print working directory
cd /path/to/dir      # Change directory
cd ~                 # Home directory
cd -                 # Previous directory
cd ..                # Up one level
ls -la               # List all files with details
ls -lh               # Human-readable sizes
ls -lt               # Sort by modification time
tree -L 2            # Tree view, 2 levels deep

File Operations

# Create
touch file.txt        # Create empty file or update timestamp
mkdir -p dir/sub/dir  # Create directory tree

# Copy / Move
cp file.txt backup.txt       # Copy file
cp -r dir/ dir_backup/       # Copy directory recursively
mv old.txt new.txt           # Move / rename
rsync -av src/ dest/         # Sync with progress

# Delete
rm file.txt                  # Delete file
rm -rf directory/            # Delete directory recursively (careful!)
rmdir emptydir/              # Delete empty directory only

# View
cat file.txt            # Print entire file
less file.txt           # Page through file (q to quit)
head -n 20 file.txt     # First 20 lines
tail -n 20 file.txt     # Last 20 lines
tail -f /var/log/app.log # Follow live (Ctrl+C to stop)

Pipes and Redirects

# Redirects
command > file.txt       # Stdout to file (overwrite)
command >> file.txt      # Stdout to file (append)
command 2> err.txt       # Stderr to file
command 2>&1             # Stderr → stdout (merge)
command &> all.txt       # Both stdout and stderr to file
command < file.txt       # Stdin from file

# Pipes
ls -la | grep ".sh"      # Pipe stdout to grep
cat file | sort | uniq   # Sort and deduplicate
ps aux | grep nginx | grep -v grep  # Find process

# Process substitution
diff <(ls dir1) <(ls dir2)  # Compare output of two commands

# Here string
grep "pattern" <<< "search in this string"

# Here document
cat <<EOF > config.yaml
key: value
other: value
EOF

Finding Files

find . -name "*.log"              # Find by name
find . -name "*.log" -newer ref   # Modified after ref file
find . -size +10M                 # Files > 10MB
find . -type f -empty             # Empty files
find . -mtime -7                  # Modified in last 7 days
find . -perm 777                  # Files with 777 permissions
find . -name "*.log" -delete      # Find and delete
find . -name "*.sh" -exec chmod +x {} \;  # Find and exec

# Locate (faster, uses a database)
locate filename
updatedb                          # Update locate database

Text Processing

# grep
grep "pattern" file.txt           # Basic search
grep -i "pattern" file.txt        # Case-insensitive
grep -r "pattern" ./dir/          # Recursive
grep -n "pattern" file.txt        # Show line numbers
grep -v "pattern" file.txt        # Invert (not matching)
grep -E "regex+" file.txt         # Extended regex
grep -c "pattern" file.txt        # Count matches

# sed (stream editor)
sed 's/old/new/' file.txt         # Replace first on each line
sed 's/old/new/g' file.txt        # Replace all occurrences
sed -i 's/old/new/g' file.txt     # Edit file in-place
sed -n '5,10p' file.txt           # Print lines 5–10
sed '/pattern/d' file.txt         # Delete matching lines

# awk
awk '{print $1}' file.txt         # Print first column
awk '{print $NF}' file.txt        # Print last column
awk -F: '{print $1}' /etc/passwd  # Use : as delimiter
awk 'NR==5' file.txt              # Print line 5
awk '/pattern/{print $0}' file    # Print matching lines
awk '{sum+=$1} END{print sum}'    # Sum first column

# sort / uniq
sort file.txt                     # Alphabetical sort
sort -n file.txt                  # Numerical sort
sort -rn file.txt                 # Reverse numerical
sort -k2 file.txt                 # Sort by 2nd column
sort file.txt | uniq              # Remove duplicates
sort file.txt | uniq -c           # Count duplicates
sort file.txt | uniq -d           # Show only duplicates

# cut / tr / wc
cut -d: -f1 /etc/passwd           # Cut field 1, delimiter :
cut -c1-10 file.txt               # Cut chars 1–10
tr 'a-z' 'A-Z' < file            # Lowercase to uppercase
tr -d '\r' < file > clean         # Remove Windows line endings
wc -l file.txt                    # Count lines
wc -w file.txt                    # Count words

Variables and Strings

# Variables
NAME="Alice"
echo $NAME
echo "${NAME} Smith"    # Curly braces for clarity

# Special variables
$0    # Script name
$1-$9 # Positional arguments
$@    # All arguments as array
$#    # Number of arguments
$?    # Exit code of last command
$$    # Current PID
$!    # PID of last background command

# String manipulation
${#NAME}              # Length
${NAME:0:3}           # Substring (0-indexed, 3 chars)
${NAME,,}             # Lowercase
${NAME^^}             # Uppercase
${NAME/old/new}       # Replace first
${NAME//old/new}      # Replace all
${NAME:-default}      # Use default if empty
${NAME:?error msg}    # Error if empty

Conditionals

# if / elif / else
if [[ "$VAR" == "value" ]]; then
  echo "match"
elif [[ "$VAR" -gt 10 ]]; then
  echo "greater"
else
  echo "no match"
fi

# Common test operators
[[ -f file ]]    # File exists
[[ -d dir ]]     # Directory exists
[[ -z "$VAR" ]]  # Variable is empty
[[ -n "$VAR" ]]  # Variable is not empty
[[ "$A" == "$B" ]] # String equality
[[ "$A" -eq "$B" ]] # Numeric equality
[[ "$A" -lt "$B" ]] # Less than

# Short-circuit
command && echo "success" || echo "failed"

Loops

# for loop
for i in 1 2 3; do echo $i; done
for i in {1..10}; do echo $i; done
for f in *.txt; do echo "$f"; done

# while loop
while [[ $COUNT -lt 10 ]]; do
  echo $COUNT
  ((COUNT++))
done

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

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

Functions

say_hello() {
  local name="$1"       # local scopes variable to function
  echo "Hello, $name!"
}

say_hello "Alice"       # Call: Hello, Alice!

# Return values (via exit codes or stdout)
add() {
  echo $(($1 + $2))
}
result=$(add 3 4)       # result=7

Process Management

command &            # Run in background
jobs                 # List background jobs
fg %1                # Bring job 1 to foreground
kill %1              # Kill job 1
kill -9 <PID>        # Force kill by PID
wait                 # Wait for all background jobs

nohup command &      # Run immune to hangups
disown %1            # Disown background job (survives terminal close)

Useful One-Liners

# Find and replace in all .conf files
find . -name "*.conf" -exec sed -i 's/old/new/g' {} \;

# Count files by extension
find . -type f | sed 's/.*\.//' | sort | uniq -c | sort -rn

# Get public IP
curl -s ifconfig.me

# Check port is open
nc -zv hostname 443

# Disk usage of subdirectories
du -sh */ | sort -rh | head -20

# Extract just IP from ifconfig/ip
ip addr show eth0 | grep "inet " | awk '{print $2}' | cut -d/ -f1

# Watch a command every 2 seconds
watch -n 2 'df -h'

# Last 10 commands with timestamps
HISTTIMEFORMAT="%F %T " history | tail -n 10

# Base64 encode/decode
echo "hello" | base64
echo "aGVsbG8K" | base64 -d

# JSON pretty print
cat file.json | python3 -m json.tool
echo '{"key":"val"}' | jq .

# Generate random password
openssl rand -base64 16

# Archive and compress
tar -czvf archive.tar.gz directory/  # Create gzip
tar -xzvf archive.tar.gz             # Extract
tar -tzvf archive.tar.gz             # List contents

Script Template

#!/usr/bin/env bash
# Script: my-script.sh
# Description: Brief description
# Usage: ./my-script.sh [arg1] [arg2]

set -euo pipefail    # Exit on error, undefined var, pipe failure
IFS=$'\n\t'          # Safer IFS

# ── Variables ──────────────────────────────────────────────────
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly LOG_FILE="${SCRIPT_DIR}/output.log"

# ── Functions ──────────────────────────────────────────────────
log() { echo "[$(date '+%F %T')] $*" | tee -a "$LOG_FILE"; }
die() { log "ERROR: $*"; exit 1; }

# ── Main ───────────────────────────────────────────────────────
main() {
  [[ $# -lt 1 ]] && die "Usage: $0 <argument>"
  local arg="${1}"
  log "Starting with arg: ${arg}"
  # ... your logic here
  log "Done"
}

main "$@"