Bash Scripting Cheatsheet

Comprehensive reference guide for Bash shell scripting. Search, browse, and learn essential Bash commands, syntax, and best practices for writing robust shell scripts.

240 commands
Getting Started

Script Header

#!/usr/bin/env bashRecommended shebang for portability
#!/bin/bashDirect path shebang
set -euo pipefailStrict mode: exit on error, unset vars, pipe failures
IFS=$'\n\t'Set Internal Field Separator to newline and tab

💡 Always use strict mode for safer scripts

Getting Started

Variables

name="John"Define variable (no spaces around =)
echo $nameUse variable
echo "$name"Use variable (recommended)
echo "${name}!"Use variable with braces
readonly name="John"Define constant variable
local name="John"Local variable (inside function)
unset nameUnset/delete variable
Getting Started

String Quotes

echo "Hi $name"Double quotes: variables expanded
echo 'Hi $name'Single quotes: literal string
echo "I'm in $(pwd)"Command substitution in string
Getting Started

Shell Execution

$(command)Command substitution (preferred)
`command`Command substitution (legacy)
eval "$cmd"Execute string as command
Getting Started

Conditional Execution

cmd1 && cmd2Run cmd2 if cmd1 succeeds
cmd1 || cmd2Run cmd2 if cmd1 fails
cmd1 ; cmd2Run both commands sequentially
cmd &Run command in background
Variables

Parameter Expansion Basics

${name}Variable value
${name/J/j}Substitution: John → john
${name:0:2}Substring: position 0, length 2
${name::2}Substring: first 2 chars
${name::-1}Substring: remove last char
${name:(-1)}Substring: last char only
${#name}Length of variable
Variables

Default Values

${foo:-val}$foo, or val if unset/null
${foo:=val}Set $foo to val if unset/null
${foo:+val}val if $foo is set (not null)
${foo:?message}Error and exit if $foo unset/null

💡 Omit : to only check if unset (not null)

Variables

String Manipulation

${str%suffix}Remove shortest suffix match
${str%%suffix}Remove longest suffix match
${str#prefix}Remove shortest prefix match
${str##prefix}Remove longest prefix match
${str/from/to}Replace first match
${str//from/to}Replace all matches
${str/#from/to}Replace prefix
${str/%from/to}Replace suffix
Variables

Case Manipulation

${str,}Lowercase first character
${str,,}Lowercase all characters
${str^}Uppercase first character
${str^^}Uppercase all characters
Variables

Path Manipulation

${path%.cpp}Remove extension: /path/to/foo
${path##*/}Get basename: foo.cpp
${path%/*}Get directory: /path/to
${path##*.}Get extension: cpp
Conditionals

If Statement

if [[ condition ]]; thenStart if block
elif [[ condition ]]; thenElse if
elseElse block
fiEnd if block
Conditionals

String Conditions

[[ -z "$str" ]]String is empty
[[ -n "$str" ]]String is not empty
[[ "$a" == "$b" ]]Strings are equal
[[ "$a" != "$b" ]]Strings are not equal
[[ "$a" < "$b" ]]String a is less than b (alphabetically)
[[ "$a" =~ regex ]]String matches regex
Conditionals

Numeric Conditions

[[ $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
(( a < b ))Arithmetic comparison
Conditionals

File Conditions

[[ -e file ]]File exists
[[ -f file ]]Is a regular file
[[ -d file ]]Is a directory
[[ -r file ]]File is readable
[[ -w file ]]File is writable
[[ -x file ]]File is executable
[[ -s file ]]File size > 0 bytes
[[ -h file ]]Is a symlink
[[ f1 -nt f2 ]]f1 is newer than f2
[[ f1 -ot f2 ]]f1 is older than f2
Conditionals

Logical Operators

[[ ! expr ]]Not
[[ expr1 && expr2 ]]And
[[ expr1 || expr2 ]]Or
Conditionals

Case Statement

case "$var" inStart case statement
pattern1) commands ;;Pattern with commands
pattern1|pattern2) cmd ;;Multiple patterns
*) default ;;Default case
esacEnd case statement
Loops

For Loop

for i in /etc/rc.*; doLoop over files
for i in {1..5}; doLoop over range
for i in {5..50..5}; doRange with step
for ((i=0; i<10; i++)); doC-style for loop
for i in "${arr[@]}"; doLoop over array
doneEnd loop
Loops

While Loop

while [[ condition ]]; doWhile loop
while true; doInfinite loop
while read -r line; doRead file line by line
done < file.txtRead from file
done < <(command)Read from command output
Loops

Until Loop

until [[ condition ]]; doLoop until condition is true
doneEnd loop
Loops

Loop Control

breakExit loop
break 2Exit 2 levels of loops
continueSkip to next iteration
continue 2Continue outer loop
Functions

Defining Functions

myfunc() { ... }Define function (preferred)
function myfunc { ... }Define function (alternate)
myfunc "arg1" "arg2"Call function with arguments
Functions

Function Arguments

$#Number of arguments
$*All arguments as single string
$@All arguments as separate strings
$1, $2, ...Individual arguments
$0Script name
${@:2}All arguments from 2nd
${@:2:3}3 arguments starting from 2nd

💡 Always quote $@ as "$@" to preserve arguments

Functions

Return Values

return 0Return success (0)
return 1Return failure (non-zero)
result=$(myfunc)Capture function output
local var="value"Local variable in function
Arrays

Indexed Arrays

arr=("a" "b" "c")Define array
arr[0]="value"Set element
${arr[0]}Get element
${arr[-1]}Get last element
${arr[@]}All elements
${#arr[@]}Array length
${!arr[@]}All indices
${arr[@]:1:2}Slice: from index 1, length 2
Arrays

Array Operations

arr+=("item")Append element
unset arr[2]Remove element at index
arr=("${arr[@]}")Rebuild array (remove gaps)
arr=("${arr[@]}" "${arr2[@]}")Concatenate arrays
Arrays

Associative Arrays (Dictionaries)

declare -A dictDeclare associative array
dict[key]="value"Set key-value
${dict[key]}Get value by key
${!dict[@]}All keys
${dict[@]}All values
${#dict[@]}Number of elements
unset dict[key]Delete key
Arrays

Array Iteration

for val in "${arr[@]}"; doIterate over values
for key in "${!dict[@]}"; doIterate over keys
for i in "${!arr[@]}"; doIterate with index
I/O & Redirection

Output Redirection

cmd > fileRedirect stdout to file (overwrite)
cmd >> fileRedirect stdout to file (append)
cmd 2> fileRedirect stderr to file
cmd 2>&1Redirect stderr to stdout
cmd &> fileRedirect both stdout and stderr
cmd &>> fileAppend both stdout and stderr
cmd >/dev/null 2>&1Discard all output
I/O & Redirection

Input Redirection

cmd < fileRead stdin from file
cmd <<< "string"Here string
cmd << EOF\n...\nEOFHere document
I/O & Redirection

Pipes

cmd1 | cmd2Pipe stdout to next command
cmd1 |& cmd2Pipe stdout and stderr
cmd | tee filePipe and save to file
cmd | xargs cmd2Pass output as arguments
I/O & Redirection

Process Substitution

diff <(cmd1) <(cmd2)Compare outputs of two commands
cmd > >(process)Send output to process
while read line; do ... done < <(cmd)Read command output in loop
I/O & Redirection

Reading Input

read varRead line into variable
read -r varRead without backslash escaping
read -p "Prompt: " varRead with prompt
read -s varRead silently (for passwords)
read -n 1 varRead single character
read -t 5 varRead with 5 second timeout
read -a arrRead into array
Options & Settings

Set Options

set -eExit on error (errexit)
set -uError on unset variables (nounset)
set -o pipefailFail on pipe errors
set -xPrint commands before execution (debug)
set -nCheck syntax without executing
set -vPrint shell input lines
set +eDisable errexit (+ disables)
Options & Settings

Shopt Options

shopt -s nullglobNon-matching globs expand to nothing
shopt -s failglobNon-matching globs cause error
shopt -s nocaseglobCase-insensitive globbing
shopt -s dotglobInclude hidden files in globs
shopt -s globstarEnable ** recursive glob
shopt -s extglobExtended pattern matching
Options & Settings

Getting Options

while getopts "ab:c" opt; doParse short options
case $opt in a) ... ;; esacHandle each option
$OPTARGOption argument value
$OPTINDIndex of next argument
History & Expansion

History Commands

historyShow command history
history -cClear history
!!Repeat last command
!nExecute command number n
!-nExecute nth previous command
!stringExecute last command starting with string
!?stringExecute last command containing string
History & Expansion

History Expansion

!$Last argument of previous command
!*All arguments of previous command
!^First argument of previous command
!!:nnth word of previous command
!!:s/old/new/Substitute in previous command
^old^newQuick substitution
History & Expansion

Brace Expansion

{a,b,c}Expands to: a b c
{1..5}Expands to: 1 2 3 4 5
{a..z}Expands to: a b c ... z
{1..10..2}Expands to: 1 3 5 7 9
file{1,2,3}.txtExpands to: file1.txt file2.txt file3.txt
{A,B}{1,2}Expands to: A1 A2 B1 B2
History & Expansion

Arithmetic Expansion

$((a + b))Arithmetic expression
$((a++))Increment
$((a--))Decrement
$((RANDOM % 100))Random number 0-99
declare -i numDeclare integer variable
let "num = 5 + 3"Arithmetic assignment
Advanced

Special Variables

$?Exit status of last command
$$PID of current shell
$!PID of last background process
$0Name of script
$_Last argument of previous command
${PIPESTATUS[@]}Exit statuses of pipe commands
$LINENOCurrent line number
$FUNCNAMECurrent function name
$BASH_SOURCEScript filename
Advanced

Traps & Signals

trap 'cmd' EXITRun cmd on script exit
trap 'cmd' ERRRun cmd on error
trap 'cmd' INTRun cmd on Ctrl+C
trap 'cmd' TERMRun cmd on termination
trap - EXITRemove trap
kill -SIGTERM $pidSend signal to process
Advanced

Subshells & Groups

(cmd1; cmd2)Run in subshell
{ cmd1; cmd2; }Run in current shell (group)
$(cmd)Command substitution
coproc cmdRun as coprocess

💡 Subshells don't affect parent environment

Advanced

Printf Formatting

printf "%s" "$var"Print string
printf "%d" 42Print integer
printf "%f" 3.14Print float
printf "%x" 255Print hex (ff)
printf "%05d" 42Zero-padded (00042)
printf "%-10s" "hi"Left-aligned, width 10
Advanced

Debugging

bash -x script.shRun with debug output
bash -n script.shCheck syntax only
set -xEnable debug mode
set +xDisable debug mode
echo "Debug: $var" >&2Print to stderr
type commandShow command type/location
command -v cmdCheck if command exists
Advanced

String Operations

tr 'a-z' 'A-Z'Translate characters
tr -d '\n'Delete characters
tr -s ' 'Squeeze repeated chars
cut -d':' -f1Cut field by delimiter
awk '{print $1}'Print first field
sed 's/old/new/g'Replace text

Quick Reference

Strict mode:

set -euo pipefail

Shebang:

#!/usr/bin/env bash

Debug:

bash -x script.sh

Check syntax:

bash -n script.sh