← Back to all cheatsheets
Linux
bashshellscriptinglinuxterminal

Bash Cheat Sheet

Basic Commands

pwd                     # Print working directory
cd /path/to/dir        # Change directory
cd ~                   # Go to home directory
cd -                   # Go to previous directory
cd ..                  # Go up one directory
ls                     # List files
ls -la                 # List all files with details
ls -lh                 # List with human-readable sizes

File Operations

# Create
touch file.txt         # Create empty file
mkdir dir              # Create directory
mkdir -p path/to/dir   # Create nested directories

# Copy
cp file1 file2         # Copy file
cp -r dir1 dir2        # Copy directory recursively
cp -i file dest        # Copy with confirmation

# Move/Rename
mv file1 file2         # Rename file
mv file /path/         # Move file
mv -i file dest        # Move with confirmation

# Delete
rm file                # Remove file
rm -r dir              # Remove directory recursively
rm -f file             # Force remove without confirmation
rm -rf dir             # Force remove directory (dangerous!)
rmdir dir              # Remove empty directory

# View
cat file               # Display file contents
less file              # View file with pagination
head file              # Show first 10 lines
head -n 20 file        # Show first 20 lines
tail file              # Show last 10 lines
tail -n 20 file        # Show last 20 lines
tail -f file           # Follow file (live updates)

File Permissions

Understanding Permissions

rwxrwxrwx = 777
- Owner | Group | Others
r = read (4)
w = write (2)
x = execute (1)

Changing Permissions

chmod 755 file         # rwxr-xr-x
chmod 644 file         # rw-r--r--
chmod +x script.sh     # Add execute permission
chmod -w file          # Remove write permission
chmod u+x file         # Add execute for user
chmod g-w file         # Remove write for group
chmod o+r file         # Add read for others
chmod -R 755 dir       # Recursive

# Change ownership
chown user file        # Change owner
chown user:group file  # Change owner and group
chown -R user dir      # Recursive
chgrp group file       # Change group only

Text Processing

grep "pattern" file              # Search in file
grep -i "pattern" file           # Case insensitive
grep -r "pattern" dir            # Recursive search
grep -v "pattern" file           # Invert match (exclude)
grep -n "pattern" file           # Show line numbers
grep -c "pattern" file           # Count matches
grep -l "pattern" *.txt          # List matching files
grep -w "word" file              # Match whole word
grep -E "regex" file             # Extended regex
grep -A 3 "pattern" file         # Show 3 lines after
grep -B 3 "pattern" file         # Show 3 lines before
grep -C 3 "pattern" file         # Show 3 lines context

sed - Stream Editor

sed 's/old/new/' file            # Replace first occurrence per line
sed 's/old/new/g' file           # Replace all occurrences
sed 's/old/new/gi' file          # Case insensitive replace
sed -i 's/old/new/g' file        # Edit file in-place
sed -n '10,20p' file             # Print lines 10-20
sed '5d' file                    # Delete line 5
sed '/pattern/d' file            # Delete lines matching pattern
sed 's/^/prefix/' file           # Add prefix to each line
sed 's/$/suffix/' file           # Add suffix to each line

awk - Text Processing

awk '{print $1}' file            # Print first column
awk '{print $1, $3}' file        # Print columns 1 and 3
awk -F: '{print $1}' /etc/passwd # Use : as delimiter
awk '{print NF}' file            # Print number of fields
awk '{print NR}' file            # Print line numbers
awk '/pattern/ {print $0}' file  # Print lines matching pattern
awk '{sum+=$1} END {print sum}'  # Sum first column
awk 'NR>1' file                  # Skip first line
awk '{print $NF}' file           # Print last field

cut - Extract Columns

cut -d: -f1 /etc/passwd          # Extract first field (: delimiter)
cut -d, -f1,3 file.csv           # Extract columns 1 and 3
cut -c1-10 file                  # Extract characters 1-10

sort and uniq

sort file                        # Sort alphabetically
sort -n file                     # Sort numerically
sort -r file                     # Reverse sort
sort -u file                     # Sort and remove duplicates
sort -k2 file                    # Sort by second column
uniq file                        # Remove adjacent duplicates
uniq -c file                     # Count occurrences
uniq -d file                     # Show only duplicates
sort file | uniq                 # Remove all duplicates

wc - Word Count

wc file                          # Lines, words, bytes
wc -l file                       # Count lines
wc -w file                       # Count words
wc -c file                       # Count bytes
wc -m file                       # Count characters

Redirection and Pipes

Standard Streams

command > file                   # Redirect stdout (overwrite)
command >> file                  # Redirect stdout (append)
command 2> file                  # Redirect stderr
command 2>&1                     # Redirect stderr to stdout
command &> file                  # Redirect both stdout and stderr
command < file                   # Redirect stdin
command1 | command2              # Pipe output to another command

Here Documents

cat << EOF > file.txt
Line 1
Line 2
EOF

cat << 'EOF' > file.sh
#!/bin/bash
echo "Script content"
EOF

Process Substitution

diff <(command1) <(command2)     # Compare command outputs
while read line; do
  echo "$line"
done < <(command)

Variables

Variable Assignment

# Variable assignment (no spaces!)
name="value"
num=42

# Using variables
echo $name
echo ${name}
echo "Hello $name"
echo "Hello ${name}!"

# Read-only variable
readonly PI=3.14159

# Environment variable
export VAR="value"

# Unset variable
unset VAR

Special Variables

$0                               # Script name
$1, $2, $3, ...                  # Positional parameters
$#                               # Number of arguments
$@                               # All arguments (separate words)
$*                               # All arguments (single word)
$?                               # Exit status of last command
$$                               # Process ID of current shell
$!                               # Process ID of last background job

Variable Manipulation

# Length
${#var}                          # Length of variable

# Substring
${var:start:length}              # Extract substring
${var:5}                         # From position 5 to end

# Replace
${var/old/new}                   # Replace first occurrence
${var//old/new}                  # Replace all occurrences

# Remove prefix/suffix
${var#pattern}                   # Remove shortest match from start
${var##pattern}                  # Remove longest match from start
${var%pattern}                   # Remove shortest match from end
${var%%pattern}                  # Remove longest match from end

# Default values
${var:-default}                  # Use default if unset
${var:=default}                  # Set to default if unset
${var:+value}                    # Use value if set
${var:?error}                    # Display error if unset

Conditionals

if Statement

if [ condition ]; then
  # commands
fi

if [ condition ]; then
  # commands
else
  # commands
fi

if [ condition1 ]; then
  # commands
elif [ condition2 ]; then
  # commands
else
  # commands
fi

Test Operators

# String comparisons
[ "$a" = "$b" ]                  # Equal
[ "$a" != "$b" ]                 # Not equal
[ -z "$a" ]                      # Empty string
[ -n "$a" ]                      # Non-empty string

# Numeric comparisons
[ "$a" -eq "$b" ]                # Equal
[ "$a" -ne "$b" ]                # Not equal
[ "$a" -lt "$b" ]                # Less than
[ "$a" -le "$b" ]                # Less than or equal
[ "$a" -gt "$b" ]                # Greater than
[ "$a" -ge "$b" ]                # Greater than or equal

# File tests
[ -e file ]                      # Exists
[ -f file ]                      # Regular file
[ -d dir ]                       # Directory
[ -L link ]                      # Symbolic link
[ -r file ]                      # Readable
[ -w file ]                      # Writable
[ -x file ]                      # Executable
[ -s file ]                      # Non-empty file
[ file1 -nt file2 ]              # Newer than
[ file1 -ot file2 ]              # Older than

# Logical operators
[ condition1 ] && [ condition2 ]  # AND
[ condition1 ] || [ condition2 ]  # OR
[ ! condition ]                   # NOT

Modern Test Syntax

# [[ ]] is preferred (bash-specific)
[[ $a == $b ]]                   # Pattern matching
[[ $a =~ regex ]]                # Regex matching
[[ $a < $b ]]                    # Lexicographic comparison
[[ -e file && -r file ]]         # Combine tests

case Statement

case "$var" in
  pattern1)
    # commands
    ;;
  pattern2|pattern3)
    # commands
    ;;
  *)
    # default
    ;;
esac

Loops

for Loop

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

# Range
for i in {1..10}; do
  echo $i
done

# List
for item in item1 item2 item3; do
  echo $item
done

# Files
for file in *.txt; do
  echo $file
done

# Array
for item in "${array[@]}"; do
  echo $item
done

while Loop

while [ condition ]; do
  # commands
done

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

# Infinite loop
while true; do
  # commands
  sleep 1
done

until Loop

until [ condition ]; do
  # commands
done

Loop Control

break                            # Exit loop
continue                         # Skip to next iteration

Functions

Function Definition

# Method 1
function_name() {
  # commands
}

# Method 2
function function_name {
  # commands
}

# With parameters
greet() {
  echo "Hello, $1!"
}
greet "World"

# With return value
add() {
  return $(($1 + $2))
}
add 5 3
echo $?  # 8

# Return string via echo
get_name() {
  echo "John"
}
name=$(get_name)

Local Variables

my_function() {
  local var="local value"
  echo "$var"
}

Arrays

Array Operations

# Declaration
arr=(val1 val2 val3)
declare -a arr

# Assignment
arr[0]="value"

# Access
echo ${arr[0]}                   # First element
echo ${arr[@]}                   # All elements
echo ${arr[*]}                   # All elements (single word)
echo ${#arr[@]}                  # Array length
echo ${!arr[@]}                  # Array indices

# Append
arr+=(new_value)

# Slice
echo ${arr[@]:start:length}

# Iterate
for item in "${arr[@]}"; do
  echo "$item"
done

# Associative arrays (bash 4+)
declare -A map
map[key1]="value1"
map[key2]="value2"
echo ${map[key1]}
echo ${!map[@]}                  # Keys
echo ${map[@]}                   # Values

Command Substitution

# Modern syntax
result=$(command)
files=$(ls)
date=$(date +%Y-%m-%d)

# Old syntax (backticks)
result=`command`

# Nested
outer=$(echo "Inner: $(echo "Hello")")

Arithmetic

Integer Arithmetic

# $(( )) syntax
result=$((5 + 3))
result=$((a * b))
((count++))
((count += 5))

# let command
let result=5+3
let "result = a * b"

# expr command (old style)
result=$(expr 5 + 3)

# Operators
a=$((5 + 3))                     # Addition
a=$((10 - 4))                    # Subtraction
a=$((6 * 7))                     # Multiplication
a=$((15 / 3))                    # Division
a=$((17 % 5))                    # Modulo
a=$((2 ** 8))                    # Exponentiation

Floating Point

# Use bc for floating point
result=$(echo "scale=2; 10/3" | bc)
result=$(bc <<< "scale=4; 22/7")

Process Management

Background Jobs

command &                        # Run in background
jobs                             # List background jobs
fg %1                            # Bring job 1 to foreground
bg %1                            # Resume job 1 in background
kill %1                          # Kill job 1
disown %1                        # Remove job from shell

Process Control

ps                               # List processes
ps aux                           # Detailed process list
ps aux | grep process            # Find process
top                              # Interactive process viewer
htop                             # Better process viewer
kill PID                         # Terminate process
kill -9 PID                      # Force kill
killall name                     # Kill by name
pkill pattern                    # Kill by pattern
pgrep pattern                    # Find process by pattern

Signals

kill -l                          # List signals
kill -TERM PID                   # Terminate (default)
kill -HUP PID                    # Hangup
kill -INT PID                    # Interrupt (Ctrl+C)
kill -KILL PID                   # Force kill (cannot be caught)
kill -STOP PID                   # Stop process
kill -CONT PID                   # Continue process

Script Best Practices

Shebang and Options

#!/bin/bash

# Strict mode
set -euo pipefail
# -e: Exit on error
# -u: Exit on undefined variable
# -o pipefail: Exit on pipe failure

# Debug mode
set -x                           # Print commands before execution

Error Handling

# Check command success
if ! command; then
  echo "Command failed"
  exit 1
fi

# Exit on error
command || exit 1

# Custom error handler
error_exit() {
  echo "Error: $1" >&2
  exit 1
}

command || error_exit "Command failed"

# Trap errors
trap 'echo "Error on line $LINENO"' ERR

# Cleanup on exit
cleanup() {
  rm -f /tmp/tempfile
}
trap cleanup EXIT

Input Validation

# Check argument count
if [ $# -ne 2 ]; then
  echo "Usage: $0 arg1 arg2"
  exit 1
fi

# Check if file exists
if [ ! -f "$file" ]; then
  echo "File not found: $file"
  exit 1
fi

# Read user input
read -p "Enter your name: " name
read -sp "Enter password: " password  # Silent
read -t 10 -p "Quick answer: " answer # Timeout

Useful Shortcuts

Command Line Editing

Ctrl+A                           # Move to beginning of line
Ctrl+E                           # Move to end of line
Ctrl+U                           # Delete from cursor to beginning
Ctrl+K                           # Delete from cursor to end
Ctrl+W                           # Delete word before cursor
Ctrl+Y                           # Paste deleted text
Ctrl+L                           # Clear screen
Ctrl+R                           # Search command history
Ctrl+C                           # Cancel current command
Ctrl+D                           # Exit shell / EOF
Ctrl+Z                           # Suspend current process
!!                               # Repeat last command
!$                               # Last argument of previous command
!*                               # All arguments of previous command
!n                               # Execute command number n from history

History

history                          # Show command history
history | grep pattern           # Search history
!123                             # Execute command 123 from history
!-2                              # Execute 2nd last command
!!                               # Repeat last command
!cmd                             # Repeat last command starting with cmd
^old^new                         # Replace old with new in last command
history -c                       # Clear history

Common Patterns

Check if Command Exists

if command -v git &> /dev/null; then
  echo "git is installed"
fi

# Alternative
if type git &> /dev/null; then
  echo "git is installed"
fi

Iterate Over Files

# Safe iteration
while IFS= read -r -d '' file; do
  echo "$file"
done < <(find . -type f -print0)

# Simple iteration
for file in *; do
  [ -f "$file" ] || continue
  echo "$file"
done

Parse Command Output

# Read into array
IFS=$'\n' read -d '' -ra lines < <(command)

# Process line by line
while IFS= read -r line; do
  echo "$line"
done < <(command)

Temporary Files

# Create temp file
tmpfile=$(mktemp)
trap "rm -f $tmpfile" EXIT

# Create temp directory
tmpdir=$(mktemp -d)
trap "rm -rf $tmpdir" EXIT

Logging

# Log to file and stdout
log() {
  echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" | tee -a logfile.log
}

log "Starting process"
log "Process complete"

Check if Running as Root

if [ "$EUID" -ne 0 ]; then
  echo "Please run as root"
  exit 1
fi

Progress Indicator

# Simple spinner
spinner() {
  local pid=$1
  local delay=0.1
  local spinstr='|/-\'
  while ps -p $pid > /dev/null; do
    local temp=${spinstr#?}
    printf " [%c]  " "$spinstr"
    local spinstr=$temp${spinstr%"$temp"}
    sleep $delay
    printf "\b\b\b\b\b\b"
  done
}

long_command &
spinner $!

Tips

  1. Quote variables: Always use "$var" to prevent word splitting
  2. Use [[ ]]: Prefer [[ ]] over [ ] for tests in bash
  3. Use shellcheck: Run shellcheck script.sh to find issues
  4. Use functions: Break complex scripts into functions
  5. Error handling: Always check command return values
  6. Use local variables: Declare function variables as local
  7. Avoid parsing ls: Use globs or find instead
  8. Use arrays: For lists of items, use arrays not strings
  9. Comment your code: Explain non-obvious logic
  10. Use meaningful names: Choose descriptive variable names
  11. Check dependencies: Verify required commands exist
  12. Handle signals: Use trap for cleanup operations
  13. Use $(command): Prefer over backticks for command substitution
  14. Validate input: Always validate user input and arguments
  15. Use readonly: For constants, use readonly VAR=value