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
Navigation
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 "$@"