Bash Cheat Sheet

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

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

Configuration Files

TIP: 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

TIP: “$’\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]

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