Cheat sheet and tricks for the Bash Unix shell and scripting language.

Single quotes (‘) and double quotes (“) are treated differently. Variables are not replaced when using single quotes.
Configuration Files

To change the command line message user@hostname, edit the PS1 variable or set PROMPT_ALTERNATIVE=oneline.
~/.bashrc
System-wide configuration
/etc/bash.bashrc
Custom environment variables and alias (made permanent in ~/.bashrc)
KALI_IP=$(hostname -I | cut -d " " -f2)
alias SET_KALI_IP='KALI_IP=$(hostname -I | cut -d " " -f2)'
Command substitution
Preferred method
USER=$(whoami)
Older method
See note on Command Substitution.
USER=`whoami`
Debug Mode
#!/bin/bash -x
Or add this at the beginning of the script (after shebang)
set -vx
Variables & Arguments
$0 # Script name
$1..$9 # Script arguments
$# # Number of arguments passed to script
$@ # All arguments passed to script
$? # Exit code of last command/process
$$ # Process ID of script
$USER # User running the script
$HOSTNAME # Machine host name
$RANDOM # Random generated number
$LINENO # Line number in script
Override global variable in function
Variables have a global scope by default.
local VAR="Some value"
Functions
read USER_INPUT
echo $USER_INPUT
read -p 'Please enter your username: ' USERNAME
read -sp 'Please enter your password' PASS
function myfunc {
echo "$1 $2"
}
myfunc a b
Conditions

Brackets execute the test function. Keep the surrounding spaces within the brackets. For information on available conditions, use man test command.
if [ <conditions> ]; then
echo "In if"
elif [ <condition1> ] && [ <condition2> ]; then
echo "In elif1"
elif [ <condition1> ] || [ <condition2> ]; then
echo "In elif2"
else
echo "In else"
fi
if [ "$#" -ne 1 ]; then
echo "Usage: $0 ARG1"
echo "Example: $0 /var/log/apache2/access.log"
# If the right number of argument was provided
else
echo "Starting program..."
fi
Loops

“$’\r’: command not found” when running a bash script is often caused by Windows’ CRLF line ending. Use command “dos2unix <filename>” to fix the issue.
Bashoneliners.com | Brace expansion
For Loop
for VAR in <list>; do
echo $VAR
done
Port scan
IP=x.x.x.x
for PORT in {1..65535}; do timeout .1 bash -c "echo >/dev/tcp/$IP/$PORT" && echo "port $PORT is open" >> ports-${IP}.txt; done; echo "Done"
cat ports-${IP}.txt
Port scan 2
-z is used for scanning, could also do “nc -znv $IP 1-65535” or “nc -znv $IP 21 80 443 445”
IP=x.x.x.x
for PORT in {1..65535}; do nc -w 3 -z -nv $IP $PORT; done
One-liners
for i in {1..10}; do echo "Debug: $i"; sleep 1; done
for i in {a..d}; do echo "Debug: $i"; sleep 1; done
for i in $(seq 1 10); do echo "Debug: $i"; sleep 1; done
for file in $(grep -Ril "password" .); do grep "password" $file; done
for IP in $(cat ~/config/IPs.txt | grep -v '#'); do echo $IP; ~/scripts/somescript.sh; done
for IP in $(cat ~/config/IPs.txt | grep -v '#'); do nmap -T4 -sT -p 1-65535 $IP > /root/nmap_allports_${IP}; done
for SUBDOMAIN in $(cat subdomains.txt | grep -v '#'); do host $SUBDOMAIN; done
for LINE in $(cat creds.txt); do export USER=$(echo $LINE | cut -d ':' -f1); export PASS=$(echo $LINE | cut -d ':' -f2); echo $USER $PASS; proxychains -q smbclient \\\\${IP}\\C$ -U "$USER%$PASS"; done
for IP in {1..254}; do ping -c 1 -w 5 x.x.x.${IP}; done
# Port scan
IP=x.x.x.x
for PORT in {1..65535}; do timeout .1 bash -c "echo >/dev/tcp/$IP/$PORT" && echo "port $PORT is open"; done; echo "Done"
# Port scan
IP=x.x.x.x
$ (for i in {1..65535}; do echo >/dev/tcp/${IP}/$i && echo $i; done) 2>/dev/null
# 2 for loops
for PORT in 22 80 443; do for IP in x.x.x.x y.y.y.y; do echo "$IP $PORT";done;done
for PORT in $(cat ~/config/ports.txt | grep -v '#'); do for IP in $(cat ~/config/IPs.txt | grep -v '#'); do echo "$IP $PORT";done;done
While Loop
i=1
while [ $i -le 10 ]; do
echo $i
((i++))
done
Bash History
Type and use Tab to autocomplete. Autocomplete scripts are located at /usr/share/bash-completion. Command history is saved by default in ~/.bash_history.
Show command history
history
History expansion: replay a command from history
!<line number from history>
!1
Replay last command
!!
[arrow up]
Reverse-i-search
Search in command history.

Ctrl+R is based on the readline library. Type “man readline” for more options. Every application that uses this library have the same functionality (example python).
[Ctrl+R]
<type first letter, second to narrow down, etc.>
[Enter]
Environment variables (made permanent in ~/.bashrc)
HISTCONTROL=ignoredups # remove duplicates from history
HISTSIZE=10000 # Nb of commands stored in memory for current session
HISTFILESIZE=10000000 # Nb of commands kept in history file
HISTIGNORE="ls:ll:cd:pwd:bg:fg:history" # Ignore common commands
HISTTIMEFORMAT='%F %T ' # yyyy-mm-dd 24:00:00
HISTTIMEFORMAT='%Y-%m-%d %T ' # yyyy-mm-dd 24:00:00