cheat sheet

Bash Cheat Sheet

Commands, scripting patterns, and shortcuts - searchable, filterable, copy-ready.

/ to focus
Navigation
POSIX
basic
Print working directory
pwd
Change directory
cd /path/to/dir
Go to home directory
cd ~
Go back one level
cd ..
Go to previous directory
cd -
List files (long + hidden)
ls -la
List sorted by modification time
ls -lt
Environment Variables
POSIX
basic
Print a variable
echo $HOME
Set and export variable
export MY_VAR="hello"
List all env variables
env
Unset a variable
unset MY_VAR
Append to PATH
export PATH="$PATH:/new/path"
History & Help
POSIX
basic
Show command history
history
Re-run last command
!!
Reverse history search
Ctrl+R
Manual page
man ls
Find where a command lives
which python3
Show command type
type cd
Create & Delete
POSIX
basic
Create empty file
touch file.txt
Create directory
mkdir mydir
Create nested directories
mkdir -p a/b/c
Remove file
rm file.txt
Remove directory recursively
rm -rf mydir/
Copy, Move & Rename
POSIX
basic
Copy a file
cp source.txt dest.txt
Copy directory recursively
cp -r src/ dest/
Move or rename
mv old.txt new.txt
Create symbolic link
ln -s /target /link-name
View & Find
POSIXGNU
intermediate
Print file contents
cat file.txt
View with pager
less file.txt
First N lines
head -n 20 file.txt
Last N lines
tail -n 20 file.txt
Follow file in real time
tail -f app.log
Find files by name
find . -name "*.log"
Find files modified in last 24h
find . -mtime -1 -type f
Disk usage of directory
du -sh mydir/
Free disk space
df -h
grep
POSIXGNU
intermediate
Search for pattern in file
grep "error" app.log
Case-insensitive search
grep -i "error" app.log
Recursive search in directory
grep -r "TODO" ./src/
Show line numbers
grep -n "error" app.log
Invert match
grep -v "debug" app.log
Extended regex (alternation)
grep -E "error|warn|fatal" app.log
Show N lines of context
grep -C 3 "error" app.log
sed & awk
POSIXGNU
advanced
Replace all matches globally
sed 's/foo/bar/g' file.txt
Edit file in-place (GNU)
sed -i 's/foo/bar/g' file.txt
Delete lines matching pattern
sed '/^#/d' file.txt
Print specific column
awk '{print $2}' file.txt
Sum a numeric column
awk '{sum+=$1} END{print sum}' file.txt
Custom field separator
awk -F: '{print $1}' /etc/passwd
xargs
POSIXGNU
intermediate
Pass stdin lines as arguments
cat files.txt | xargs rm
Handle filenames with spaces
find . -name "*.tmp" -print0 | xargs -0 rm
Run N jobs in parallel
cat urls.txt | xargs -P 4 -I{} curl -O {}
Pipes & Redirection
POSIX
intermediate
Redirect stdout to file
echo "hello" > out.txt
Append to file
echo "world" >> out.txt
Redirect stderr to file
command 2> errors.log
Redirect both stdout and stderr
command > out.txt 2>&1
Discard all output
command > /dev/null 2>&1
Sort, count, rank
cat file.txt | sort | uniq -c | sort -rn
Process Management
POSIX
intermediate
List all running processes
ps aux
Interactive process viewer
top
Find PID by name
pgrep nginx
Kill process by PID
kill 1234
Force kill (SIGKILL)
kill -9 1234
Kill all processes by name
pkill nginx
Background & Jobs
POSIX
intermediate
Run command in background
long-command &
List background jobs
jobs
Bring job to foreground
fg %1
Resume suspended job in background
bg %1
Run immune to terminal close
nohup command > out.log 2>&1 &
Suspend foreground process
Ctrl+Z
Script Skeleton & Special Vars
POSIX
scripting
Recommended shebang
#!/usr/bin/env bash
Strict mode
set -euo pipefail
Special variables
$0 # script name $1 # first argument $@ # all arguments $# # argument count $? # last exit code $$ # current shell PID
Make executable and run
chmod +x script.sh && ./script.sh
Variables & Strings
POSIX
scripting
Assign variable (no spaces around =)
name="Alice"
Command substitution
today=$(date +%Y-%m-%d)
Arithmetic expansion
result=$((5 * 3 + 2))
Default value if unset
echo "${MY_VAR:-default}"
String length
echo ${#name}
Substring (offset:length)
echo ${name:0:3}
Uppercase / lowercase (bash 4+)
echo ${name^^} # ALICE echo ${name,,} # alice
Arrays (bash 4+)
bash 4+
scripting
Declare indexed array
fruits=("apple" "banana" "cherry")
Access by index / all elements / length
echo "${fruits[0]}" # apple echo "${fruits[@]}" # all echo "${#fruits[@]}" # length
Append to array
fruits+=("mango")
Loop over array
for f in "${fruits[@]}"; do echo "$f" done
Associative array (dictionary)
declare -A colors colors[red]="#ff0000" colors[blue]="#0000ff" echo "${colors[red]}"
Loop over associative array keys
for key in "${!colors[@]}"; do echo "$key = ${colors[$key]}" done
Conditionals & Regex
POSIX
scripting
if / elif / else
if [ "$x" -gt 10 ]; then echo "big" elif [ "$x" -eq 10 ]; then echo "ten" else echo "small" fi
Common test flags
[ -f file ] # is regular file [ -d path ] # is directory [ -z "$v" ] # string is empty [ -n "$v" ] # string is non-empty
Regex match with =~
if [[ "$email" =~ ^[a-z]+@[a-z]+\.[a-z]+$ ]]; then echo "valid" fi
Capture regex groups via BASH_REMATCH
str="2026-04-27" [[ "$str" =~ ([0-9]{4})-([0-9]{2}) ]] echo "${BASH_REMATCH[1]}" # 2026 echo "${BASH_REMATCH[2]}" # 04
Loops
POSIX
scripting
for with brace expansion
for i in {1..5}; do echo $i; done
for over files
for f in *.txt; do echo "Processing: $f" done
while loop
n=5 while [ $n -gt 0 ]; do echo $n; ((n--)) done
Read file line by line (safe)
while IFS= read -r line; do echo "$line" done < file.txt
Functions
POSIX
scripting
Define and call a function
greet() { local name="$1" echo "Hello, $name" } greet "World"
Return value via stdout
add() { echo $(($1 + $2)); } result=$(add 3 5) echo $result # 8
Here-docs & Here-strings
POSIX
scripting
Here-doc (multi-line stdin)
cat <<EOF Hello $USER, Today is $(date). EOF
Here-doc to a file
cat <<EOF > config.txt host=localhost port=8080 EOF
Here-string (single string to stdin)
grep "hello" <<< "hello world"
trap - Signal Handling
POSIX
scripting
Cleanup on exit (always runs)
cleanup() { rm -f /tmp/my.lock; } trap cleanup EXIT
Handle Ctrl+C (SIGINT)
trap 'echo "Interrupted"; exit 1' INT
Trap on error with line number
trap 'echo "Error on line $LINENO"' ERR
Remove a trap
trap - EXIT
Common signal names
EXIT INT TERM ERR HUP
cron & crontab
POSIX
scripting
Edit crontab
crontab -e
List crontab
crontab -l
Crontab field order
# min hour dom month dow command # * * * * * /path/script.sh
Every day at midnight
0 0 * * * /path/to/script.sh
Every 15 minutes
*/15 * * * * /path/to/script.sh
Shorthand aliases
@hourly @daily @weekly @monthly @reboot
curl
POSIX
intermediate
GET request
curl https://api.example.com
POST JSON body
curl -X POST -H "Content-Type: application/json" \ -d '{"key":"value"}' https://api.example.com
Download file
curl -O https://example.com/file.zip
Follow redirects
curl -L https://example.com
Response headers only
curl -I https://example.com
Set Authorization header
curl -H "Authorization: Bearer $TOKEN" https://api.example.com
Network Diagnostics
POSIXGNU
intermediate
Ping a host
ping -c 4 google.com
DNS lookup
nslookup example.com
Show listening ports
ss -tuln
Show network interfaces
ip addr show
SSH into server
ssh user@hostname
Copy file over SSH
scp file.txt user@host:/remote/path/
Sync directories (rsync)
rsync -avz src/ user@host:/dest/
chmod
POSIX
intermediate
Make file executable
chmod +x script.sh
Owner read/write only (SSH keys)
chmod 600 ~/.ssh/id_rsa
Standard file permissions
chmod 644 file.txt
Standard script permissions
chmod 755 script.sh
Recursive permission change
chmod -R 755 mydir/
Numeric reference
7=rwx 6=rw- 5=r-x 4=r--
chown & sudo
POSIX
intermediate
Change owner and group
chown user:group file.txt
Recursive ownership change
chown -R www-data:www-data /var/www/
Run command as root
sudo command
Open root shell
sudo -i
Show current user and groups
id
tar
POSIXGNU
intermediate
Create .tar.gz archive
tar -czf archive.tar.gz mydir/
Extract .tar.gz archive
tar -xzf archive.tar.gz
Extract to specific directory
tar -xzf archive.tar.gz -C /target/dir/
List archive contents
tar -tzf archive.tar.gz
Create .tar.bz2 (better compression)
tar -cjf archive.tar.bz2 mydir/
Create .tar.xz (best compression)
tar -cJf archive.tar.xz mydir/
gzip & zip
POSIX
intermediate
Compress a file
gzip file.txt
Decompress
gunzip file.txt.gz
Compress keeping original
gzip -k file.txt
Read compressed without extracting
zcat file.txt.gz
Create zip archive
zip -r archive.zip mydir/
Extract zip archive
unzip archive.zip
List zip contents
unzip -l archive.zip
Keyboard Shortcuts
basic
Move to beginning of line
Ctrl+A
Move to end of line
Ctrl+E
Delete word before cursor
Ctrl+W
Cut to end of line
Ctrl+K
Cut to start of line
Ctrl+U
Paste last cut text
Ctrl+Y
Clear terminal screen
Ctrl+L
Interrupt current process
Ctrl+C
Suspend current process
Ctrl+Z
Reverse history search
Ctrl+R
Move one word forward
Alt+F
Move one word backward
Alt+B
Delete word forward
Alt+D
Useful One-liners
advanced
Count lines in file
wc -l file.txt
Top 10 largest files
du -ah . | sort -rh | head -10
Kill process on port 3000
kill $(lsof -t -i:3000)
Repeat command every 2 seconds
watch -n 2 df -h
Run only if previous succeeded
make && ./run.sh
Timestamped backup
cp file.txt "file.txt.$(date +%Y%m%d_%H%M%S)"
Generate random password
openssl rand -base64 32
Time how long a command takes
time ./my-script.sh

This Bash cheat sheet covers everything you need to work efficiently in the terminal, from basic navigation to advanced scripting patterns.

Bash is the default shell on Linux and most Unix-based systems. It's also a full scripting language. Knowing it well saves you hours.

What's Inside

  • Basics - navigation, environment variables, history, and help commands

  • Files & Directories - create, delete, copy, move, find, and inspect files

  • Text & Search - grep, sed, awk, xargs, pipes, and redirection

  • Processes - manage running processes, background jobs, and signals

  • Scripting - variables, arrays, loops, functions, conditionals, here-docs, trap, and cron

  • Network - curl, SSH, SCP, rsync, and diagnostics

  • Permissions - chmod, chown, and sudo patterns

  • Archive - tar, gzip, zip, and extraction commands

  • Shortcuts - keyboard shortcuts and useful one-liners

Who It's For

Developers, sysadmins, and DevOps engineers who work in the terminal daily. Also useful for anyone writing automation scripts or managing servers.

Every snippet is copy-ready. Most include a preview showing expected output or behavior. Compatibility badges mark which commands are POSIX-safe, GNU-specific, or require bash 4+.

Strict mode, signal handling, regex matching, associative arrays -- the parts that trip people up are all here, with working examples.

What is Bash

Bash is the Bourne-Again SHell, a Unix shell and command language that ships as the default login shell on most Linux distributions.

It works as both an interactive command-line interface and a scripting engine for automating tasks on Linux and Unix systems.

Developed by Brian Fox for the GNU Project in 1989, Bash replaced the original Bourne Shell (sh) while staying backward compatible with POSIX standards.


How Does Bash Differ from Other Shells

Bash supports arrays, arithmetic expansion, and command history out of the box - features sh lacks.

Zsh adds smarter tab completion and plugin ecosystems (Oh My Zsh).

Fish prioritizes user-friendliness with syntax highlighting and autosuggestions, but breaks POSIX compatibility.

Bash stays the safest choice for cross-platform shell scripting across Linux, macOS, and Windows Subsystem for Linux (WSL).


Bash Syntax

What is the Bash Shebang Line

#!/bin/bash goes on the very first line of any bash script.

It tells the OS to use the bash interpreter, not whatever shell the current user runs.

Without it, the script may execute under sh or another shell, breaking bash-specific syntax.

What Are Bash Comments

Single-line comments start with #.

Multi-line comments use the : '...' workaround - not a true comment block, but widely used in bash shell scripting.

How Do Bash Quoting Rules Work

  • Single quotes '...' - literal string, no expansion

  • Double quotes "..." - allows $variable and command substitution

  • Backticks cmd - command substitution (prefer $(cmd) instead)

  • Backslash \ - escapes single characters


Bash Variables

How Do You Declare and Use Variables in Bash

NAME="John"
echo "$NAME"     # John
echo "${NAME}!"  # John!
NAME = "John"    # Error - no spaces around =

Always quote variables: "$NAME" prevents word splitting and glob expansion.

Variable Types in Bash

  • Local variables - exist only in the current shell session

  • Environment variables - exported with export VAR=value, inherited by child processes

  • Special variables - $0 (script name), $1$9 (positional args), $# (arg count), $@ (all args), $? (last exit code), $$ (current PID)

  • Read-only variables - set with readonly VAR=value

How Does String Manipulation Work in Bash

Bash handles string operations directly through parameter expansion - no external tools needed for basic tasks.

Operation

Syntax

Result

Length

${#var}

character count

Substring

${var:2:4}

chars at offset 2, length 4

Replace first

${var/old/new}

one substitution

Replace all

${var//old/new}

all matches

Strip prefix

${var#prefix}

removes shortest match

Strip suffix

${var%suffix}

removes shortest match

Uppercase

${var^^}

all caps

Lowercase

${var,,}

all lowercase

What Are Bash Arrays

# Indexed array
fruits=("apple" "banana" "cherry")
echo "${fruits[0]}"    # apple
echo "${fruits[@]}"    # all elements
echo "${#fruits[@]}"   # array length

# Associative array
declare -A colors
colors["red"]="#FF0000"
echo "${colors["red"]}"

Iterate with for item in "${fruits[@]}".


Bash Operators

What Are Bash Arithmetic Operators

Use $(( )) for integer math - no external tools required.

echo $((5 + 3))    # 8
echo $((10 % 3))   # 1
echo $((2 ** 8))   # 256

let and expr work too, but $(( )) is faster and cleaner.

What Are Bash Comparison Operators

[ ] is POSIX-compatible.

[[ ]] is bash-specific - safer, supports regex with =~, no need to quote variables.

Integer Comparison Operators Table

Operator

Meaning

-eq

equal to

-ne

not equal to

-lt

less than

-gt

greater than

-le

less than or equal

-ge

greater than or equal

String Comparison Operators Table

Operator

Meaning

= or ==

strings are equal

!=

strings are not equal

-z

string is empty

-n

string is not empty

What Are Bash File Test Operators

File tests go inside [ ] or [[ ]].

Operator

True when

-f file

file exists and is a regular file

-d file

directory exists

-r file

readable

-w file

writable

-x file

executable

-s file

file exists and size > 0

-e file

exists (any type)

if [[ -f "/etc/hosts" ]]; then
  echo "File exists"
fi

Bash Control Flow

How Do If Statements Work in Bash

if [[ "$name" == "John" ]]; then
  echo "Hello John"
elif [[ "$name" == "Jane" ]]; then
  echo "Hello Jane"
else
  echo "Who are you?"
fi

Use && and || for inline conditionals: [[ -f file ]] && echo "exists".

How Do For Loops Work in Bash

# List iteration
for fruit in apple banana cherry; do
  echo "$fruit"
done

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

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

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

How Do While and Until Loops Work in Bash

count=0
while [[ $count -lt 5 ]]; do
  echo "$count"
  ((count++))
done

until runs while the condition is false - the inverse of while.

Use break to exit a loop early; continue to skip to the next iteration.

How Does a Case Statement Work in Bash

case "$1" in
  start | up)
    echo "Starting..."
    ;;
  stop | down)
    echo "Stopping..."
    ;;
  *)
    echo "Usage: $0 {start|stop}"
    ;;
esac

Cleaner than chained if/elif blocks when matching one variable against multiple patterns.


Bash Functions

How Do You Define and Call Functions in Bash

greet() {
  echo "Hello, $1"
}

greet "World"    # Hello, World

Both function greet { } and greet() { } syntax work.

Parameters use $1, $2, etc. - no argument declaration needed.

How Do You Return Values from Bash Functions

return only exits with a status code (0–255) - not a value.

To capture actual output, use command substitution:

get_name() { echo "John"; }
name=$(get_name)
echo "$name"    # John

Check exit status with $? after any function call.

What is Variable Scope in Bash Functions

All variables are global by default - even ones set inside functions.

Use local to restrict scope:

myfunc() {
  local x=10
  echo "$x"
}
# $x is unavailable here

Bash Input and Output

How Do Bash Redirections Work

Syntax

Action

cmd > file

overwrite file with stdout

cmd >> file

append stdout to file

cmd < file

read stdin from file

cmd 2> file

redirect stderr

cmd 2>&1

merge stderr into stdout

cmd > /dev/null

discard output

What is Piping in Bash

| passes the stdout of one command as stdin to the next.

ls -la | grep ".sh" | wc -l

Pipes chain commands; redirections connect commands to files.

How Does Here Document (Heredoc) Work in Bash

cat <<EOF
Line one
Line two
EOF

Use <<-EOF to allow indented content.

Heredocs pass multi-line input to commands - useful for generating config files or SQL queries inside scripts.

What is Process Substitution in Bash

diff <(ls dir1) <(ls dir2)

<(command) treats command output as a temporary file.

Works where a filename is expected but you only have command output - can't be piped.


Bash File and Directory Commands

What Are the Core Bash File Management Commands

Command

Purpose

ls -la

list all files with permissions

cp -r src/ dst/

copy directory recursively

mv file.txt /path/

move or rename

rm -rf dir/

delete directory (no undo)

mkdir -p a/b/c

create nested directories

touch file.txt

create empty file or update timestamp

find . -name "*.sh"

find files by name pattern

chmod +x script.sh

make file executable

How Do You Search File Contents in Bash

grep -rn "search_term" ./          # recursive, with line numbers
grep -i "pattern" file.txt         # case-insensitive
grep -v "exclude" file.txt         # invert match

sed handles find-and-replace in files; awk extracts and processes columns.


Bash Process Management

How Do You Manage Processes in Bash

ps aux                 # list all processes
kill 1234              # terminate PID 1234
kill -9 1234           # force kill
nohup ./script.sh &    # run after logout

Find a PID with ps aux | grep process_name or pgrep process_name.

What Are Background and Foreground Jobs in Bash

./script.sh &      # run in background
jobs               # list background jobs
fg %1              # bring job 1 to foreground
bg %1              # resume job 1 in background

Ctrl+Z suspends the current foreground process; Ctrl+C terminates it.


Bash Scripting Patterns

How Do You Handle Script Arguments in Bash

echo "Script: $0"
echo "First arg: $1"
echo "All args: $@"
echo "Arg count: $#"

shift removes $1 and shifts remaining args down.

For flag parsing, use getopts:

while getopts "f:v" opt; do
  case $opt in
    f) file="$OPTARG" ;;
    v) verbose=true ;;
  esac
done

How Do You Handle Errors in Bash Scripts

set -e           # exit on any error
set -u           # error on undefined variables
set -o pipefail  # catch errors in pipes
set -euo pipefail  # all three together (common pattern)

Add a trap for cleanup on errors:

trap 'echo "Error on line $LINENO"' ERR

How Do You Debug a Bash Script

bash -n script.sh    # syntax check only
bash -x script.sh    # trace execution
set -x               # enable trace inside script
set +x               # disable trace

ShellCheck catches bugs statically before you run anything - use it.

What is the Difference Between [ ] and [[ ]] in Bash

[ ] is POSIX-portable but fragile - unquoted variables cause word splitting.

[[ ]] is bash-specific, supports regex matching with =~, handles empty variables safely, and is the right choice for any bash script.

[[ "$str" =~ ^[0-9]+$ ]] && echo "numeric"

Bash Keyboard Shortcuts

What Are the Most Useful Bash Keyboard Shortcuts

Learn these and you'll move through the terminal twice as fast.

Ctrl+R reverse-searches your bash command history.

Ctrl+L clears the screen without wiping history; Ctrl+C kills the current process; Ctrl+D closes the session.

Navigation Shortcuts

Shortcut

Action

Ctrl+A

move to start of line

Ctrl+E

move to end of line

Alt+F

move forward one word

Alt+B

move backward one word

Editing Shortcuts

Shortcut

Action

Ctrl+U

cut from cursor to line start

Ctrl+K

cut from cursor to line end

Ctrl+W

cut previous word

Ctrl+Y

paste (yank) cut text

History Shortcuts

Shortcut

Action

Ctrl+R

reverse search history

!!

repeat last command

!$

last argument of previous command

!n

run command number n from history


Bash Configuration Files

What Are Bash Configuration Files

File

Loaded when

~/.bashrc

interactive non-login shell (new terminal tab)

~/.bash_profile

login shell (SSH, first login)

~/.bash_logout

on logout

~/.bash_history

stores command history

Most desktop terminals load ~/.bashrc.

SSH sessions load ~/.bash_profile - a common source of "my alias works locally but not on the server" confusion.

How Do You Create Bash Aliases

alias ll='ls -la'
alias gs='git status'
alias ..='cd ..'

Add aliases to ~/.bashrc for persistence.

unalias ll removes one; unalias -a removes all.


Bash String Operations

How Do You Perform String Operations in Bash

str="Hello World"
echo "${#str}"           # 11 (length)
echo "${str^^}"          # HELLO WORLD
echo "${str,,}"          # hello world
echo "${str/World/Bash}" # Hello Bash
[[ "$str" == *"World"* ]] && echo "contains World"

Split a string by setting IFS:

IFS=',' read -ra parts <<< "a,b,c"
echo "${parts[0]}"    # a

String Manipulation Reference

Operation

Syntax

Result

Length

${#var}

character count

Substring

${var:2:3}

3 chars from offset 2

Replace first

${var/old/new}

one substitution

Replace all

${var//old/new}

all matches

Strip prefix

${var#prefix}

removes shortest match

Strip suffix

${var%suffix}

removes shortest match


Bash Conditional Expressions

What Are Bash Logical Operators

Inside [[ ]]: use && (AND), || (OR), ! (NOT).

[[ -f file && -r file ]] && echo "readable file"
[[ ! -d dir ]] && mkdir dir

Between commands: cmd1 && cmd2 runs cmd2 only if cmd1 succeeds; cmd1 || cmd2 runs cmd2 only if cmd1 fails.

How Does Brace Expansion Work in Bash

echo {a,b,c}.txt          # a.txt b.txt c.txt
mkdir project/{src,tests,docs}
echo {1..5}               # 1 2 3 4 5
echo {a..z}               # a b c d ... z
cp config.yaml{,.bak}     # quick backup trick

Brace expansion runs before any other expansion - no files need to exist.

Works inside for loops, mkdir, cp, mv, and anywhere a list of values is needed.

FAQ on Bash Cheat Sheets

What is a bash cheat sheet used for?

A bash cheat sheet is a quick reference for bash shell commands, syntax, and scripting patterns.

It saves time by keeping the most-used commands - file operations, loops, conditionals, redirections - in one scannable place instead of digging through man pages.

What are the most important bash commands to know?

ls, cd, cp, mv, rm, find, grep, chmod, and echo cover most daily Linux terminal work.

For bash scripting, add if, for, while, case, and function syntax to that list.

What is the difference between bash and shell scripting?

Shell scripting is the broad concept - writing scripts for any Unix shell.

Bash scripting is shell scripting specifically using the Bourne-Again SHell, which adds arrays, arithmetic expansion, and [[ ]] conditionals beyond basic POSIX sh.

How do I run a bash script?

Make it executable with chmod +x script.sh, then run it with ./script.sh.

Alternatively, call it directly with bash script.sh - no execute permission needed. Always start scripts with the #!/bin/bash shebang line.

What does $? mean in bash?

$? holds the exit code of the last executed command.

0 means success; any non-zero value means failure. Scripts commonly check $? after commands to decide whether to continue or trigger error handling.

What is the difference between single and double quotes in bash?

Single quotes preserve every character literally - no variable expansion, no special characters processed.

Double quotes allow $variable substitution and command substitution with $(), but still protect spaces and most special characters from the shell.

How do I debug a bash script?

Run bash -x script.sh to trace each command as it executes.

Add set -euo pipefail at the top of any script to catch errors, undefined variables, and failed pipes early. Tools like ShellCheck catch syntax issues before runtime.

What are bash special variables?

Special variables include $0 (script name), $1$9 (positional arguments), $# (argument count), $@ (all arguments), $$ (current process ID), and $! (last background process ID).

These are read-only and set automatically by the shell.

How do I loop through files in bash?

Use a for loop with glob expansion:

for file in *.txt; do
  echo "$file"
done

Always quote "$file" inside the loop to handle filenames with spaces correctly. Works across all Linux distributions without extra tools.

What is the safest way to write bash scripts?

Start every script with set -euo pipefail - exits on errors, catches undefined variables, and prevents silent pipe failures.

Use [[ ]] instead of [ ], quote all variables, and run scripts through ShellCheck before deploying to any production environment.