BASH SCRIPTING
BASICS#
#!/bin/bash # Shebang chmod +x script.sh # Make executable ./script.sh # Run script bash script.sh # Run with bash source script.sh # Run in current shell . script.sh # Same as source
VARIABLES#
VAR="value" # Assign variable
echo $VAR # Access variable
echo ${VAR} # Same, with braces
echo "${VAR}" # Quoted (preserves spaces)
readonly VAR # Make read-only
unset VAR # Delete variable
export VAR # Make available to subprocesses
# Special variables
$0 # Script name
$1, $2, ... # Positional arguments
$# # Number of arguments
$@ # All arguments (separate)
$* # All arguments (single string)
$? # Exit status of last command
$$ # Current process ID
$! # Last background process ID
$_ # Last argument of previous command
# Variable substitution
${VAR:-default} # Use default if unset
${VAR:=default} # Set default if unset
${VAR:+value} # Use value if set
${VAR:?error} # Error if unset
${#VAR} # Variable length
${VAR:0:5} # Substring (offset:length)
${VAR#pattern} # Remove shortest prefix
${VAR##pattern} # Remove longest prefix
${VAR%pattern} # Remove shortest suffix
${VAR%%pattern} # Remove longest suffix
${VAR/old/new} # Replace first match
${VAR//old/new} # Replace all matches
${VAR^} # Uppercase first char
${VAR^^} # Uppercase all
${VAR,} # Lowercase first char
${VAR,,} # Lowercase all
ARRAYS#
arr=(one two three) # Declare array
arr[0]="value" # Set element
echo ${arr[0]} # Get element
echo ${arr[@]} # All elements
echo ${#arr[@]} # Array length
echo ${!arr[@]} # Array indices
arr+=(four) # Append element
unset arr[1] # Remove element
# Associative arrays (bash 4+)
declare -A map
map[key]="value"
echo ${map[key]}
echo ${!map[@]} # All keys
CONDITIONALS#
# if/elif/else
if [ condition ]; then
commands
elif [ condition ]; then
commands
else
commands
fi
# Test operators ([ ] or test)
-eq # Equal (numeric)
-ne # Not equal (numeric)
-lt # Less than
-le # Less or equal
-gt # Greater than
-ge # Greater or equal
= # Equal (string)
!= # Not equal (string)
-z # Empty string
-n # Non-empty string
-f # File exists
-d # Directory exists
-r # Readable
-w # Writable
-x # Executable
-s # File not empty
-L # Symbolic link
-e # Exists (any type)
! # Negation
-a # AND
-o # OR
# Extended test [[ ]]
[[ $a == $b ]] # String comparison
[[ $a =~ regex ]] # Regex match
[[ -f $file && -r $file ]] # AND
[[ $a == "yes" || $a == "y" ]] # OR
# Arithmetic (( ))
(( a > b )) # Comparison
(( a++ )) # Increment
(( a += 5 )) # Add and assign
# Case statement
case $var in
pattern1)
commands
;;
pattern2|pattern3)
commands
;;
*)
default
;;
esac
LOOPS#
# For loop
for i in 1 2 3; do
echo $i
done
for i in {1..10}; do
echo $i
done
for i in {1..10..2}; do # Step by 2
echo $i
done
for file in *.txt; do
echo $file
done
for ((i=0; i<10; i++)); do
echo $i
done
# While loop
while [ condition ]; do
commands
done
while read line; do
echo $line
done < file.txt
# Until loop
until [ condition ]; do
commands
done
# Break and continue
break # Exit loop
continue # Next iteration
FUNCTIONS#
function_name() {
commands
return 0
}
function function_name {
commands
}
# Call function
function_name arg1 arg2
# Function arguments
$1, $2, ... # Arguments
$@ # All arguments
return value # Return status
# Local variables
local var="value"
INPUT/OUTPUT#
echo "text" # Print
echo -n "no newline" # No newline
echo -e "tab\ttab" # Interpret escapes
printf "format" args # Formatted output
read var # Read input
read -p "prompt: " var # Prompt
read -s var # Silent (passwords)
read -t 5 var # Timeout
read -a arr # Read into array
# Redirection
command > file # Stdout to file
command >> file # Append stdout
command 2> file # Stderr to file
command 2>&1 # Stderr to stdout
command &> file # Both to file
command < file # Stdin from file
command <<< "string" # Here string
command << EOF # Here document
text
EOF
# Pipes
cmd1 | cmd2 # Pipe stdout
cmd1 |& cmd2 # Pipe stdout and stderr
ARITHMETIC#
result=$((a + b)) # Arithmetic expansion ((a++)) # Increment ((a--)) # Decrement ((a += 5)) # Add and assign let "a = 5 + 3" # Let command expr 5 + 3 # expr command
STRING OPERATIONS#
${#string} # String length
${string:0:5} # Substring
${string/old/new} # Replace
${string^^} # Uppercase
${string,,} # Lowercase
# Comparison
[[ $a == $b ]] # Equal
[[ $a != $b ]] # Not equal
[[ $a < $b ]] # Less than (alphabetic)
[[ $a =~ regex ]] # Regex match
PROCESS HANDLING#
command & # Run in background jobs # List jobs fg %1 # Bring to foreground bg %1 # Send to background kill %1 # Kill job wait # Wait for background jobs wait $pid # Wait for specific process $! # Last background PID $$ # Current PID
TRAPS#
trap 'commands' SIGNAL # Handle signal trap 'cleanup' EXIT # Run on exit trap 'error_handler' ERR # Run on error trap '' SIGNAL # Ignore signal # Common signals SIGINT (2) # Interrupt (Ctrl+C) SIGTERM (15) # Terminate SIGHUP (1) # Hangup EXIT # Script exit
ERROR HANDLING#
set -e # Exit on error
set -u # Error on undefined var
set -o pipefail # Pipe fails if any command fails
set -x # Debug mode
# Best practice
set -euo pipefail
# Check command success
if command; then
echo "success"
else
echo "failed"
fi
command || echo "failed"
command && echo "success"
DEBUGGING#
bash -x script.sh # Debug mode
set -x # Enable debug
set +x # Disable debug
PS4='+ ${LINENO}: ' # Custom debug prompt
USEFUL PATTERNS#
# Check if root
[[ $EUID -eq 0 ]] || exit 1
# Check command exists
command -v cmd &>/dev/null || exit 1
# Process arguments
while [[ $# -gt 0 ]]; do
case $1 in
-f|--file)
FILE="$2"
shift 2
;;
-v|--verbose)
VERBOSE=1
shift
;;
*)
echo "Unknown: $1"
shift
;;
esac
done
# Loop files safely
while IFS= read -r -d '' file; do
echo "$file"
done < <(find . -type f -print0)
BASH SCRIPTING CHEATSHEET
=========================
Source: https://cheatsheet.johlem.net
BASICS
------
#!/bin/bash # Shebang
chmod +x script.sh # Make executable
./script.sh # Run script
bash script.sh # Run with bash
source script.sh # Run in current shell
. script.sh # Same as source
VARIABLES
---------
VAR="value" # Assign variable
echo $VAR # Access variable
echo ${VAR} # Same, with braces
echo "${VAR}" # Quoted (preserves spaces)
readonly VAR # Make read-only
unset VAR # Delete variable
export VAR # Make available to subprocesses
# Special variables
$0 # Script name
$1, $2, ... # Positional arguments
$# # Number of arguments
$@ # All arguments (separate)
$* # All arguments (single string)
$? # Exit status of last command
$$ # Current process ID
$! # Last background process ID
$_ # Last argument of previous command
# Variable substitution
${VAR:-default} # Use default if unset
${VAR:=default} # Set default if unset
${VAR:+value} # Use value if set
${VAR:?error} # Error if unset
${#VAR} # Variable length
${VAR:0:5} # Substring (offset:length)
${VAR#pattern} # Remove shortest prefix
${VAR##pattern} # Remove longest prefix
${VAR%pattern} # Remove shortest suffix
${VAR%%pattern} # Remove longest suffix
${VAR/old/new} # Replace first match
${VAR//old/new} # Replace all matches
${VAR^} # Uppercase first char
${VAR^^} # Uppercase all
${VAR,} # Lowercase first char
${VAR,,} # Lowercase all
ARRAYS
------
arr=(one two three) # Declare array
arr[0]="value" # Set element
echo ${arr[0]} # Get element
echo ${arr[@]} # All elements
echo ${#arr[@]} # Array length
echo ${!arr[@]} # Array indices
arr+=(four) # Append element
unset arr[1] # Remove element
# Associative arrays (bash 4+)
declare -A map
map[key]="value"
echo ${map[key]}
echo ${!map[@]} # All keys
CONDITIONALS
------------
# if/elif/else
if [ condition ]; then
commands
elif [ condition ]; then
commands
else
commands
fi
# Test operators ([ ] or test)
-eq # Equal (numeric)
-ne # Not equal (numeric)
-lt # Less than
-le # Less or equal
-gt # Greater than
-ge # Greater or equal
= # Equal (string)
!= # Not equal (string)
-z # Empty string
-n # Non-empty string
-f # File exists
-d # Directory exists
-r # Readable
-w # Writable
-x # Executable
-s # File not empty
-L # Symbolic link
-e # Exists (any type)
! # Negation
-a # AND
-o # OR
# Extended test [[ ]]
[[ $a == $b ]] # String comparison
[[ $a =~ regex ]] # Regex match
[[ -f $file && -r $file ]] # AND
[[ $a == "yes" || $a == "y" ]] # OR
# Arithmetic (( ))
(( a > b )) # Comparison
(( a++ )) # Increment
(( a += 5 )) # Add and assign
# Case statement
case $var in
pattern1)
commands
;;
pattern2|pattern3)
commands
;;
*)
default
;;
esac
LOOPS
-----
# For loop
for i in 1 2 3; do
echo $i
done
for i in {1..10}; do
echo $i
done
for i in {1..10..2}; do # Step by 2
echo $i
done
for file in *.txt; do
echo $file
done
for ((i=0; i<10; i++)); do
echo $i
done
# While loop
while [ condition ]; do
commands
done
while read line; do
echo $line
done < file.txt
# Until loop
until [ condition ]; do
commands
done
# Break and continue
break # Exit loop
continue # Next iteration
FUNCTIONS
---------
function_name() {
commands
return 0
}
function function_name {
commands
}
# Call function
function_name arg1 arg2
# Function arguments
$1, $2, ... # Arguments
$@ # All arguments
return value # Return status
# Local variables
local var="value"
INPUT/OUTPUT
------------
echo "text" # Print
echo -n "no newline" # No newline
echo -e "tab\ttab" # Interpret escapes
printf "format" args # Formatted output
read var # Read input
read -p "prompt: " var # Prompt
read -s var # Silent (passwords)
read -t 5 var # Timeout
read -a arr # Read into array
# Redirection
command > file # Stdout to file
command >> file # Append stdout
command 2> file # Stderr to file
command 2>&1 # Stderr to stdout
command &> file # Both to file
command < file # Stdin from file
command <<< "string" # Here string
command << EOF # Here document
text
EOF
# Pipes
cmd1 | cmd2 # Pipe stdout
cmd1 |& cmd2 # Pipe stdout and stderr
ARITHMETIC
----------
result=$((a + b)) # Arithmetic expansion
((a++)) # Increment
((a--)) # Decrement
((a += 5)) # Add and assign
let "a = 5 + 3" # Let command
expr 5 + 3 # expr command
STRING OPERATIONS
-----------------
${#string} # String length
${string:0:5} # Substring
${string/old/new} # Replace
${string^^} # Uppercase
${string,,} # Lowercase
# Comparison
[[ $a == $b ]] # Equal
[[ $a != $b ]] # Not equal
[[ $a < $b ]] # Less than (alphabetic)
[[ $a =~ regex ]] # Regex match
PROCESS HANDLING
----------------
command & # Run in background
jobs # List jobs
fg %1 # Bring to foreground
bg %1 # Send to background
kill %1 # Kill job
wait # Wait for background jobs
wait $pid # Wait for specific process
$! # Last background PID
$$ # Current PID
TRAPS
-----
trap 'commands' SIGNAL # Handle signal
trap 'cleanup' EXIT # Run on exit
trap 'error_handler' ERR # Run on error
trap '' SIGNAL # Ignore signal
# Common signals
SIGINT (2) # Interrupt (Ctrl+C)
SIGTERM (15) # Terminate
SIGHUP (1) # Hangup
EXIT # Script exit
ERROR HANDLING
--------------
set -e # Exit on error
set -u # Error on undefined var
set -o pipefail # Pipe fails if any command fails
set -x # Debug mode
# Best practice
set -euo pipefail
# Check command success
if command; then
echo "success"
else
echo "failed"
fi
command || echo "failed"
command && echo "success"
DEBUGGING
---------
bash -x script.sh # Debug mode
set -x # Enable debug
set +x # Disable debug
PS4='+ ${LINENO}: ' # Custom debug prompt
USEFUL PATTERNS
---------------
# Check if root
[[ $EUID -eq 0 ]] || exit 1
# Check command exists
command -v cmd &>/dev/null || exit 1
# Process arguments
while [[ $# -gt 0 ]]; do
case $1 in
-f|--file)
FILE="$2"
shift 2
;;
-v|--verbose)
VERBOSE=1
shift
;;
*)
echo "Unknown: $1"
shift
;;
esac
done
# Loop files safely
while IFS= read -r -d '' file; do
echo "$file"
done < <(find . -type f -print0)
Defensive reference on CyberRamen. Offensive / red-team sheets live on OffensiveRamen.com.