Bash Cheat Sheet
Shell scripting and one-liners: variables, conditionals, loops, functions, job control, and string manipulation.
Variables
10VAR=valueAssign a variable (no spaces)
export VAR=valueExport to child processes
echo "$VAR"Expand the variable inside quotes
echo '$VAR'Literal, no expansion
VAR=""; unset VARClear a variable
readonly VAR=valueMake a variable immutable
read -p 'prompt> ' VARRead input into a variable
envShow the environment
echo "$PATH"Show the executable search path
export NAME=valueSet and export an environment variable
Parameter Expansion
10"${VAR:-default}"Use default if unset or empty
"${VAR:=default}"Assign a default in place
"${#VAR}"Length of the value
"${VAR:0:5}"Substring starting at 0, 5 chars
"${VAR%.*}"Remove shortest match from the end
"${VAR#prefix}"Remove shortest match from the start
"${VAR^^}"Uppercase the value
"${VAR,,}"Lowercase the value
"${VAR//OLD/NEW}"Replace all occurrences
"${VAR: -3}"Last 3 characters (note the space)
Quoting & Pipes
10CMD1 | CMD2Pipe stdout into the next command
CMD1 | tee FILEOutput to stdout and a file at once
CMD >FILE 2>&1Redirect stdout and stderr to a file
CMD &>/dev/nullDiscard both streams (bash 4+)
CMD |& lessPipe both streams (bash 4+)
CMD $(cmd)Command substitution (new-style)
CMD `cmd`Command substitution (old-style)
echo "$(date +%s)"Current Unix timestamp
a=$(cat FILE)Capture file content in a variable
<(CMD)Process substitution (treat as a file)
Conditionals
10if [ -f FILE ]; then CMD; fiRun if the file exists
if [ "$A" = "$B" ]; then CMD; fiString equality
if [ "$A" -gt 10 ]; then CMD; fiNumeric greater-than
if [ -n "$VAR" ]; then CMD; fiTrue if the variable is non-empty
if [ -z "$VAR" ]; then CMD; fiTrue if the variable is empty
if [ -d DIR ]; then CMD; fiTrue if DIR exists and is a directory
if CMD; then CMD; else CMD; fiBranch on a command's exit status
case "$1" in start) CMD;; stop) CMD;; *) echo '?'; esacSwitch on a value
[[ ARCH == *.gz ]] && CMD || CMD2Extended pattern match, ternary style
[ "$A" = "$B" ] && echo yOne-line guard
Loops
8for i in 1 2 3; do echo $i; doneLoop over literal values
for f in *.log; do gzip "$f"; doneLoop over matching files
for ((i=0; i<10; i++)); do CMD; doneC-style numeric loop
while read -r line; do echo "$line"; done < FILERead a file line by line
until ping -c1 HOST; do sleep 2; doneLoop until success
for f in $(find DIR -name '*.conf'); do CMD; doneLoop over command output
for i in {1..5}; do CMD; doneRange expansion
true && CMD || (echo 'failed' >&2; exit 1)Bail early on failure
Functions
6greet() { echo "hello $1"; }Define a function with args
die() { echo "$1" >&2; exit 1; }Error-and-exit helper
function f { return 1; }Return a status from a function
Trap 'cleanup' EXITRun cleanup on script exit
trap 'kill $PID' TERM INTForward signals to a child
export -f fnameExport a function to subshells
Job Control & Background
9CMD &Run in the background
CMD & echo $!Background and print its PID
jobs -lList background jobs with PIDs
fg %1Bring job 1 to the foreground
bg %1Resume job 1 in the background
wait $PIDWait for a background PID to finish
Ctrl+ZSuspend the foreground job
waitWait for all background jobs
set -euo pipefailStrict mode: exit on error or unset var
History & Shortcuts
10historyShow command history
!!Last command
!$Last argument of the last command
^old^newRerun last command with a substitution
Ctrl+RReverse-search history
Ctrl+CStop the current command
Ctrl+DExit shell / send EOF
Ctrl+LClear the terminal
fc -l -5Show the last 5 commands
HISTCONTROL=ignorebothIgnore duplicates and leading spaces