Bash Commands Cheat Sheet: Essential Reference

bash linux terminal shell command-line

Bash is the default shell on most Linux distributions and macOS, and the runtime behind CI pipelines, deployment scripts, and developer automation. This bash commands cheat sheet groups the most-used commands by category — navigation, file operations, text processing, I/O redirection, process management, and scripting syntax — so you can jump straight to the section you need without filtering through man pages.

Essential Bash Commands by Category

A quick-lookup overview of the command groups covered in this reference:

CategoryKey commands
Navigationcd, ls, pwd, pushd, popd, dirs
Filescp, mv, rm, mkdir, touch, find, ln
Viewingcat, less, head, tail, wc, diff
Text processinggrep, sed, awk, cut, sort, uniq
Variables$VAR, ${VAR:-default}, $(...), $((math))
I/O>, >>, <, `
Processesps, top, kill, bg, fg, jobs, nohup
Networkingcurl, ping, ssh, scp, rsync, ss
Scriptingif, for, while, case, function, set

The bash commands you run dozens of times a day:

CommandWhat it does
pwdPrint the current working directory
lsList directory contents
ls -laLong listing including hidden files
ls -lhLong listing with human-readable file sizes
ls -ltSort by modification time, newest first
ls -RList directories recursively
cd <dir>Change directory
cd ..Go up one level
cd ~Go to home directory
cd -Return to the previous directory
pushd <dir>Push directory onto stack and switch to it
popdPop directory from stack and return
dirsDisplay the directory stack
mkdir -p a/b/cCreate a nested directory path in one step
rmdir <dir>Remove an empty directory

For a wider reference covering the Linux filesystem hierarchy and system administration utilities, the Linux Commands Cheat Sheet covers broader territory including package management, disk usage, and service control.

File Operations

Copying, Moving, and Removing

CommandWhat it does
cp file.txt copy.txtCopy a file
cp -r src/ dst/Copy a directory recursively
cp -u src dstCopy only if source is newer than destination
mv old.txt new.txtRename a file
mv file.txt /tmp/Move a file to a directory
rm file.txtDelete a file
rm -rf dir/Delete a directory and all its contents
touch file.txtCreate an empty file or update timestamp
ln -s /path/to/target linkCreate a symbolic link
find . -name "*.tmp" -deleteFind and delete files matching a pattern

Viewing File Contents

CommandWhat it does
cat file.txtPrint file contents to stdout
less file.txtPage through a file (q to quit)
head -n 20 file.txtFirst 20 lines of a file
tail -n 20 file.txtLast 20 lines of a file
tail -f log.txtFollow a file as it grows (useful for logs)
wc -l file.txtCount lines
wc -w file.txtCount words
wc -c file.txtCount bytes
diff file1 file2Show line-by-line differences
stat file.txtShow file metadata (size, permissions, timestamps)

Bash Variables and Parameter Expansion

Bash variables are set without spaces around = and read with $. Single quotes prevent expansion; double quotes allow it:

name="Alice"
count=0
readonly CONFIG_DIR="/etc/myapp"

echo "$name"                    # Alice
echo "Hello, ${name}!"         # Hello, Alice!
echo "${name:-default}"        # use "default" if $name is unset or empty
echo "${name:0:3}"             # substring: first 3 chars → Ali
echo "${name^^}"               # uppercase → ALICE
echo "${#name}"                # string length → 5
echo "${name/Alice/Bob}"       # replace first match → Bob

 # Command substitution
today=$(date +%Y-%m-%d)
file_count=$(ls | wc -l)

 # Arithmetic
((count++))
result=$((count * 10 + 5))
echo "$result"

 # Arrays
servers=("web01" "web02" "db01")
echo "${servers[0]}"           # web01
echo "${servers[@]}"           # all elements
echo "${#servers[@]}"          # array length

Special variables Bash always provides:

VariableValue
$0Script name
$1$9Positional arguments
$@All arguments as separate quoted words
$*All arguments as a single word
$#Number of arguments
$?Exit status of the last command
$$PID of the current shell
$!PID of the last background process
$SECONDSSeconds elapsed since the shell started
$LINENOCurrent line number in the script
$RANDOMRandom integer 0–32767

Text Search and Processing

grep — Search Files and Streams

CommandWhat it does
grep "pattern" file.txtSearch for lines matching a pattern
grep -r "pattern" dir/Search recursively in a directory
grep -i "pattern" file.txtCase-insensitive search
grep -n "pattern" file.txtShow line numbers
grep -v "pattern" file.txtShow lines that do NOT match
grep -l "pattern" *.logList filenames that contain the pattern
grep -c "pattern" file.txtCount matching lines
grep -E "error|warn" file.txtExtended regex, match either word
grep -o "pattern" file.txtPrint only the matched text
grep -A 3 "pattern" file.txtInclude 3 lines after each match
grep -B 3 "pattern" file.txtInclude 3 lines before each match

Use the regex tester to validate patterns interactively before embedding them in scripts or grep commands.

sed — Stream Editor

sed edits text streams line by line. The most common use is substitution:

CommandWhat it does
sed 's/old/new/g' file.txtReplace all occurrences of “old” with “new”
sed -i 's/old/new/g' file.txtReplace in place (edit the file directly)
sed -i.bak 's/old/new/g' file.txtReplace in place, keep .bak backup
sed '5d' file.txtDelete line 5
sed -n '5,10p' file.txtPrint only lines 5 through 10
sed '/pattern/d' file.txtDelete lines matching a pattern
sed 's/^/PREFIX: /' file.txtPrepend text to every line
sed 's/$/ SUFFIX/' file.txtAppend text to every line

awk — Column and Record Processing

awk processes structured text (CSV, log fields, whitespace-delimited output) by splitting each line into fields:

CommandWhat it does
awk '{print $1}' file.txtPrint the first column
awk -F: '{print $1}' /etc/passwdSet delimiter to :, print first field
awk '{sum += $2} END {print sum}' file.txtSum the second column
awk 'NR==5' file.txtPrint only line 5
awk 'length > 80' file.txtPrint lines longer than 80 characters
awk '$3 > 1000 {print $1, $3}' file.txtConditional column output
awk 'NR%2==0' file.txtPrint every second line

I/O Redirection and Pipelines

Bash connects commands using stdin (0), stdout (1), and stderr (2):

OperatorEffect
command > fileWrite stdout to file, overwriting it
command >> fileAppend stdout to file
command < fileRead stdin from file
command 2> fileWrite stderr to file
command 2>&1Merge stderr into stdout
command &> fileWrite both stdout and stderr to file
command 2>/dev/nullDiscard all error output
command1 | command2Pipe stdout of command1 to stdin of command2
command | tee fileWrite stdout to a file and also to the terminal

Practical pipeline patterns:

 # Discard errors entirely
ls /nonexistent 2>/dev/null

 # Capture stdout and stderr together
output=$(command 2>&1)

 # Analyze the 20 most-requested 404 URLs in an nginx access log
cat access.log \
  | grep " 404 " \
  | awk '{print $7}' \
  | sort \
  | uniq -c \
  | sort -rn \
  | head -20

 # Write to a file and see it at the same time
make 2>&1 | tee build.log

 # Process substitution: use command output as a file argument
diff <(sort file1.txt) <(sort file2.txt)

 # Here-string: pass a string as stdin
base64 <<< "hello world"

Process and Job Management

CommandWhat it does
ps auxList all running processes
ps aux | grep nginxFind a specific process by name
topInteractive process monitor (q to quit)
htopImproved interactive monitor (if installed)
kill <pid>Send SIGTERM to a process (graceful stop)
kill -9 <pid>Send SIGKILL (force stop, cannot be caught)
killall nginxKill all processes with that exact name
pkill -f "python app.py"Kill processes matching a pattern
jobsList background and suspended jobs in this shell
bg %1Resume job 1 in the background
fg %1Bring job 1 to the foreground
command &Start a command in the background
nohup command &Run immune to hangup signal, stays after logout
disown %1Remove job 1 from the shell’s job table
waitWait for all background jobs to finish
nice -n 10 commandRun with reduced CPU scheduling priority
renice -n 5 -p <pid>Adjust priority of a running process

When running long-lived processes over SSH, pair these commands with a terminal multiplexer. The tmux Cheat Sheet covers session, window, and pane management so processes survive disconnections.

Bash Scripting Quick Reference

Conditionals

#!/usr/bin/env bash

log_file="/var/log/app.log"

 # File tests
if [[ -f "$log_file" ]]; then
    echo "Log file exists"
elif [[ -d "/var/log" ]]; then
    echo "Directory exists but no log file yet"
else
    echo "Neither exists"
fi

 # Common file test flags
 # -f  regular file exists
 # -d  directory exists
 # -e  path exists (file or directory)
 # -r  readable    -w  writable    -x  executable
 # -s  non-empty file
 # -L  symbolic link

 # String comparison
env="${DEPLOY_ENV:-development}"
if [[ "$env" == "production" ]]; then
    echo "Production mode — extra caution"
fi

 # Numeric comparison (use (()) for arithmetic)
file_count=$(ls | wc -l)
if (( file_count > 100 )); then
    echo "More than 100 files in current directory"
fi

 # Case statement
case "$1" in
    start)   systemctl start myapp ;;
    stop)    systemctl stop myapp ;;
    restart) systemctl restart myapp ;;
    *)       echo "Usage: $0 {start|stop|restart}" ;;
esac

Loops

 # For loop over a list
for service in nginx postgresql redis; do
    if systemctl is-active --quiet "$service"; then
        echo "$service is running"
    else
        echo "$service is STOPPED"
    fi
done

 # Glob expansion — iterate over files
for log in /var/log/*.log; do
    size=$(wc -l < "$log")
    echo "$log: $size lines"
done

 # C-style for loop
for (( i=1; i<=5; i++ )); do
    echo "Step $i of 5"
done

 # While loop reading a file line by line
while IFS= read -r line; do
    echo "Processing: $line"
done < input.txt

 # Until loop (opposite of while — loops until condition is TRUE)
count=0
until [[ $count -ge 5 ]]; do
    echo "count=$count"
    ((count++))
done

Functions

 # Define with the function keyword or bare name()
check_service() {
    local service_name="$1"          # always use local for function vars
    if systemctl is-active --quiet "$service_name"; then
        echo "$service_name is running"
        return 0
    else
        echo "$service_name is NOT running" >&2
        return 1
    fi
}

 # Call with arguments
check_service nginx
check_service postgresql || echo "postgresql down — alerting on-call"

 # Return values via stdout (command substitution)
get_version() {
    local app="$1"
    "$app" --version 2>&1 | head -1
}
version=$(get_version node)
echo "Node version: $version"

Error Handling

set -euo pipefail
 # -e   exit immediately on any error
 # -u   treat unset variables as errors
 # -o pipefail   pipe fails if any command in it fails

 # Trap errors and cleanup
trap 'echo "Error on line $LINENO — exiting" >&2' ERR
trap 'rm -f "/tmp/scratch_$$"' EXIT

 # Conditional execution
command1 && command2   # run command2 only if command1 succeeds
command1 || command2   # run command2 only if command1 fails

Bash History and Keyboard Shortcuts

History Commands

CommandWhat it does
historyShow full command history
history 20Show the last 20 commands
!!Repeat the last command
!grepRepeat the last command starting with grep
!<n>Repeat history entry number n
!$Last argument of the previous command
!*All arguments of the previous command
Ctrl+RReverse incremental search through history
history -cClear history for the current session
HISTSIZE=10000Number of history entries to keep in memory
HISTFILESIZE=10000Number of entries to save to ~/.bash_history

Essential Keyboard Shortcuts

ShortcutAction
Ctrl+CInterrupt / kill the foreground process
Ctrl+ZSuspend the foreground process (use fg to resume)
Ctrl+DSend EOF / exit the current shell
Ctrl+LClear the terminal screen
Ctrl+AMove cursor to the beginning of the line
Ctrl+EMove cursor to the end of the line
Ctrl+WDelete the word before the cursor
Ctrl+UDelete from the cursor to the beginning of the line
Ctrl+KDelete from the cursor to the end of the line
Alt+.Insert the last argument of the previous command
Alt+BMove cursor back one word
Alt+FMove cursor forward one word

Networking Commands

CommandWhat it does
ping -c 4 example.comSend 4 ICMP echo requests
curl -I https://example.comFetch HTTP response headers only
curl -L -o file.zip https://example.com/file.zipDownload a file, following redirects
curl -X POST -d '{"key":"val"}' -H 'Content-Type: application/json' URLPOST JSON
wget -q https://example.com/file.tar.gzDownload quietly
ssh user@hostOpen an SSH session
ssh -p 2222 user@hostSSH on a non-standard port
ssh -L 8080:localhost:80 user@hostLocal port forwarding via SSH tunnel
scp file.txt user@host:/path/Copy a file to a remote host
rsync -avz src/ user@host:dst/Sync a directory to a remote host
netstat -tlnpList listening TCP ports with PIDs
ss -tlnpFaster alternative to netstat
lsof -i :8080Show which process is using port 8080
dig example.comDNS lookup
host example.comSimple DNS resolution

For a thorough walkthrough of curl — including request headers, authentication schemes, and JSON payloads — see the curl Command Guide. When deploying from scripts, the Git Commands Cheat Sheet covers the repository operations you’ll need alongside push and pull automation. The Docker Commands Cheat Sheet pairs well for containerized deployment workflows.

The GNU Bash Manual is the authoritative reference for every built-in and shell option. The Linux man page for bash documents every flag, expansion rule, and built-in command in full detail.

Frequently Asked Questions

What is the difference between bash and sh?

sh is the POSIX shell standard — a minimal specification for shell behavior including basic conditionals, loops, and parameter expansion. bash (Bourne Again SHell) is a strict superset of sh that adds arrays, arithmetic expansion with $((...)), [[ ... ]] extended conditionals, process substitution with <(...), readline editing, and a richer history system.

On most modern Linux systems, /bin/sh is a symlink to dash or another minimal POSIX shell — not bash. Scripts with #!/bin/sh run in POSIX mode and will fail if they use bash-specific syntax like [[ ]] or arrays. Use #!/usr/bin/env bash when your script needs bash features, and #!/bin/sh only when strict POSIX portability matters (e.g., inside BusyBox or Alpine Linux containers where bash is not installed).

How do I find a file by name in bash?

Use the find command with the -name flag:

find /home -name "*.log" -type f            # all .log files under /home
find . -name "config.json" -maxdepth 3      # search up to 3 levels deep
find /tmp -mmin -30 -type f                 # files modified in the last 30 minutes
find . -name "*.pyc" -delete                # find and delete all .pyc files
find /var/log -size +100M -type f           # files larger than 100 MB

For searching text content within files, use grep -r "pattern" . instead. Combine both to locate files by name and then filter by content:

find . -name "*.conf" -exec grep -l "timeout" {} \;

How do I check which process is using a specific port?

Run one of these commands — they need sudo for processes owned by other users:

lsof -i :8080           # process name, PID, user — most readable
ss -tlnp | grep :8080   # faster; built into modern Linux kernels
netstat -tlnp | grep :8080  # classic; requires the net-tools package
fuser 8080/tcp          # returns just the PID

lsof -i :8080 is the most readable on a single server. On high-traffic servers or in scripts, ss is faster because it queries the kernel directly without the overhead of scanning /proc.

Conclusion

These bash commands cover the full daily workflow: navigating filesystems, reading and transforming text with grep, sed, and awk, managing background jobs, and writing scripts that handle errors cleanly with set -euo pipefail and traps. The scripting section is worth revisiting any time a sequence of bash commands grows beyond a one-liner — the discipline of local variables, explicit error handling, and meaningful exit codes pays back quickly in debugging time.

For terminal session management across long-running tasks, the tmux Cheat Sheet is the natural companion reference. For a broader coverage of Linux system administration commands including disk management, user control, and service configuration, the Linux Commands Cheat Sheet goes deeper on system-level utilities.