The tiny BASH Cheat Sheet
Siegfried Steiner
Siegfried Steiner
10 min read

Categories

Tags

The tiny BASH Cheet Sheet provides you (me) with a more or less alphabetically sorted tool-box of the expressions I most commonly use and tend to forget. I will update this cheat sheet now and then depending on more expressions I can’t remember :-)


Update [2019-10-12@11:12]: Added a list of internal variales + Update [2019-10-04@23:48]: Added a nifty bash script template and a pointer cheat on working with variable substitution + Update [2019-07-12@21:09]: Added cheats on working with args and provided some handy functions + Update [2018-10-13@14:33]: Added some hints on text conversions + Update [2018-09-22@16:37]: Added some information on trap handlers and the debug “interrupt”.


Args Bash script template Echo Files Functions If IFS Line segmentation Numbers Paths Read Shebang Internal variales Status codes Trap Variable substitution

Args

The variable $@ is equivalent to $1 $2 … which represent the positional parameters passed to your script. The variable $# expands to the number of positional parameters in decimal (see also bash(1): GNU Bourne-Again SHell - Linux man page).

Test number of arguments

To test the number of arguments passed to your shell script, you can use the $#variable:

if [ "$#" -ne 1 ]; then
    echo "Illegal number of parameters"
    exit 1
fi

This tests whether exactly one argument has been passed.

Bash script template

Wrapping up some of the here mentioned cheats, a nifty template for your scripts might look as follows:

#!/bin/bash
#!/bin/bash

CURRENT_DIR="$(pwd)"
SCRIPT_PATH="$(dirname $0)"
cd "${SCRIPT_PATH}"
SCRIPT_PATH="$(pwd)"
cd "${CURRENT_DIR}"
SCRIPT_DIR="${SCRIPT_PATH##*/}"
SCRIPT_NAME="$(basename $0 .sh)"
PARENT_PATH="$(realpath $(dirname $0)/..)"
PARENT_DIR="${PARENT_PATH##*/}"

RED="\E[31m"
GREEN="\E[32m"
YELLOW="\E[33m"
BLUE="\E[34m"
MAGENTA="\E[35m"
CYAN="\E[36m"
WHITE="\E[37m"
RESET="\E[0m"

function quit? {
    input=""
    while ([ "$input" != "q" ] && [ "$input" != "y" ]); do
        echo -ne "\E[32mContinue? Enter [q] to quit, [y] to continue:\E[0m ";
        read input;
    done
    # printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
    if [ "$input" == "q" ] ; then
        echo -e "> \E[31mAborting due to user input.\E[0m"
        exit
    fi
}

function fgColor {
    color=$(echo $1 | tr a-z A-Z)
    if [ -z "${!color}" ] ; then
          echo -n "<Unknown color \"$1\"!>"
    else
        echo -en "${!color}"
    fi
}

function resetColor {
    echo -en "${RESET}"
}

function printLn {
    char="-"
    if [[ $# == 1 ]] ; then
        char="$1"
    fi
    printf '%*s' "${COLUMNS:-$(tput cols)}" '' | tr ' ' ${char}
}

fgColor "cyan"
figlet -w 180 ">>>${SCRIPT_NAME}..." 2> /dev/null
if [ $? -ne 0 ]; then
    banner "${SCRIPT_NAME}..." 2> /dev/null
    if [ $? -ne 0 ]; then
        echo "> ${SCRIPT_NAME}:" | tr a-z A-Z 
    fi
fi
resetColor

# ----------------------------------------------------------------------------->
# ... put your stuff here ...
# <-----------------------------------------------------------------------------

Echo

“… echo - display a line of text …” (from man echo)

Echo new lines

text="line1\nline2\nline3\n"
echo -e "${text}"

The -e switch enables echothe interpretation of the following backslash escapes”.

Don’t echo new lines

text="line1\nline2\nline3\n"
echo "${text}"

Echo to standard error

echo  "Error" >&2
>&2 echo "Error"

Echo to standard out

echo  "Standard out"

Echo to standard out and standard error

echo "Error and out" 1>&2;

Echo ANSI escape codes

ANSI escape codes can be used to output text in various colors:

echo -e "\033[0;31m<<<Red foreground>>>\033[0m"
echo -e "\033[0;32m<<<Green foreground>>>\033[0m"
echo -e "\033[0;34m<<<Blue foreground>>>\033[0m"
echo -e "\033[30;48;5;1m<<<Red background, black foreground>>>\033[0m"
echo -e "\033[30;48;5;2m<<<Green background, black foreground>>>\033[0m"
echo -e "\033[30;48;5;4m<<<Blue background, black foreground>>>\033[0m"

The sequence \033[0m resets the escape codes being set before. The -e switch enables echothe interpretation of the following backslash escapes”. For more effects see also bash:tip_colors_and_formatting by FLOZz' MISC.

Files

“… A computer file is a computer resource for recording data discretely in a computer storage device. …” (see Computer file - Wikipedia)

Read all lines of a file

This one reads all lines of a file, including the last one not terminated with a new line:

while IFS='' read -r line || [[ -n "$line" ]]; do
  echo "${line}"
done < "/path/to/my/file.txt"

IFS stands for internal field separator and is used by the shell to determine how to do word splitting and recognize word boundaries. For other usages of read see the section on read.

Functions

“… Shell functions are a way to group commands for later execution using a single name for the group. They are executed just like a “regular” command…” (see Shell Functions (Bash Reference Manual))

Ask for continue/quit:

The below function asks whether to continue c or to quit q. The shell script will exit upon choosing q or ask again till either c or q is pressed:

function quit? {
    input=""
    while ([ "$input" != "q" ] && [ "$input" != "y" ]); do
        echo -ne "\E[32mContinue? Enter [q] to quit, [y] to continue:\E[0m ";
        read input;
    done
    # printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
    if [ "$input" == "q" ] ; then
        echo -e "> \E[31mAborting due to user input.\E[0m"
        exit
    fi
}

The below function prints a separator line using the whole width of your terminal:

function printLn {
    printf '%*s' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
}

If

“… At times you need to specify different courses of action to be taken in a shell script, depending on the success or failure of a command …” (see Introduction to if - Bash Guide for Beginners

If on sub-string

Tests if a string begins with some substring:

if [[ $line = foo* ]] ; then
  echo "Starts with \"foo\" !"
fi

If on empty variable

Tests whether a variable does not exist or is empty.

if [ -z "${var}" ] ; then
  ...
fi

If on existing variable

Tests whether a variable exist and is not empty.

if [ -n "${var}" ] ; then
  ...
fi

If on status code

Control flow depending of the error code of a called command:

false
if [ $? -ne 0 ]; then
    echo "Error!"
    exit 1
fi
echo "No error :-)"
true
if [ $? -ne 0 ]; then
    echo "Error!"
    exit 1
fi
echo "No error :-)"

A status code can also be forced instead of calling a command by issuing a true or a false, see allso the chapter on Status codes.

If on file exists

Test whether a file exists or not:

if [ -f /tmp/foo.txt ]; then
    echo "File found!"
fi

Negate the if statatement with the exclemation mark ! as follows: if [ ! -f /tmp/foo.txt ]; ...

If on directory exists

Test whether a directory exists or not:

if [ -d /home/nakatomi/tmp ]; then
    echo "Directoy exists!"
fi

Negate the if statatement with the exclemation mark ! as follows: if [ ! -d /home/nakatomi/tmp ]; ...

Internal field separator (IFS)

IFS stands for internal field separator and is used by the shell to determine how to do word splitting and recognize word boundaries.

mystring="A:B C D"
IFS=' '; for word in $mystring; do echo "Word: $word"; done
IFS=':'; for word in $mystring; do echo "Word: $word"; done

Internal variales

There are some reserved bash variables with special values, the so called internal vairables:

Variable Behhaviour
$0 Name of the shell script when invoked from within a bash script, else the name of the shell when invoked directly from the command line
$1, $2, $3, … Represents the first ($1), the second ($2) and the third ($3) argument (and so on) being passed to your bash script or bash function (arguments from the 10th onward must be enclosed in curly braces as such: ${10}, ${11}, ${12})
$* All arguments passed to your bash script or bash function in a single string, arguments separated by each other by a space (“ ”) character
$# The number of arguments passed to your bash script or bash function
$@ All arguments passed to your bash script or bash function as an array, preserving arguments of multiple words encapsulated in quotes (“"”) as a single argument
$? The status code of the last executed command
$$ The PID (process ID) of the script itself
$BASH The path of the bash shell itself
$BASH_VERSION The version of the bash shell itself
$FUNCNAME The name of the function currently being executed
$HOME The home directory of the current user, something like /home/romero
$HOSTNAME The name of the host the bash script is executed on
$IFS The internal field separator, used by the shell to determine how to do word splitting and recognize word boundaries (see IFS)
$LINENO The line number of the bash script’s line currently being executed (actually the line number where this internal variable appears)
$PATH The path where the bash shell looks for executables (binaries) or other scripts when called without a preceding path
$PS1 The bash shell’s command line’s (first) prompt, can be beautified with ANSI escape codes
$PS2, $PS3, $PS4 The secondary ($PS2, additional input expected), tertiary ($PS3, within a select loop which is a tool for building menus) and quaternary ($PS4, prefix for additional printed information in case the bash shell has been invoked with the -x switch) prompt
$PWD The current working directory of the bash shell (and therewith your bash script)
$RANDOM Contains the last pseudo random number being continuously produced
$SECONDS The number of seconds this script already runs
$USER The user name of the user executing the bash script

Line segmentation

Elements by index

Get a sub-string from a string by its index given a known delimiter:

echo "1,2,3" | cut -d ',' -f 2
echo "A B C" | cut -d ' ' -f 1
echo -e "X\tY\tZ" | cut  -f 3

The cut command is used to extract sections from lines of input.

Numbers

Count

Increment a value:

index="1"
index=$((index+1))

Paths

Remove last part of path

Given the path /usr/local/bin:

dirname /usr/local/bin

This will result in the output /usr/local.

Read

“… The read utility shall read a single line from standard input. …” (from man read)

Halt till a key is pressed

You may halt the script till a key is pressed:

echo "Hit any key ..."
read -n 1 -s 

Shebang

Depending on the shell you want to use it looks something like this at the beginning of your script file, being introduced with a shebang (“#!”):

#!/bin/bash

Status codes

If on status code

See If on status code in the If chapter.

Force status code 0

true

Force status code 1

false

Text

Convert text to lower case

echo "Lower case to upper case" | tr a-z A-Z

Convert text to upper case

echo "Upper case to lower  case" | tr A-Z a-z

Trap

“… trap [-lp] [arg] [sigspec …] … The commands in arg are to be read and executed when the shell receives signal sigspec …” (see Bash Reference Manual: Bourne Shell Builtins)

Trap signals

You may invoke your custom trap handler upon any occurrence of a control signal such as Ctrl+C, Ctrl+Y or Ctrl+Z:

trap "echo 'Bye bye!'" 1 2 3 6

For a list of signal numbers with the corresponding signals, please refer to Trap - Shell Scripting Tutorial or Signals - Bash Guide for Beginners.

Debug “interrupt”

Traps can be used for advanced functionality such as the “debug” interrupt:

#!/bin/bash
trap '
    echo "> Executing command \"$BASH_COMMAND\", press any key to continue ..."
    read -n 1 -s
' DEBUG

echo "Hello world!"
echo "Hello universe!"

Upon execution of your bash script, the trap handler is called after each invocation of your script’s commands, with the variable $BASH_COMMAND containing the bashcommand to be executed next. You may halt the script till a key is pressed (read -n 1 -s).

Variable substitution

Interpret a variable’s value as variable name

Given a variable named color contains a value which represents another variable. That other value is a color name which we want to resolve to its color value. E.g. we have a pointer to another variable in our variable named color which resolves to a color value. Now we have some colors defined as ANSI escape codes:

red="\E[31m"
green="\E[32m"
yellow="\E[33m"
blue="\E[34m"
magenta="\E[35m"
cyan="\E[36m"
white="\E[37m"

Next we assign our colorvariable the value green:

color="green"

Finally we want to get the ANSI escape codes for green:

echo ${!color}

This results in the output “\E[32m”. Now we can pass color “names” to get their ANSI escape codes as easy as color="red", color="blue or color="yellow" and so on.

Replace first

Replace the first occurrence of a string:

text="I am a very clever person, clever, isn't it?"
result=${text/clever/dumb}
echo "${result}"

Replace all

Replace all occurrences of a string:

text="I am a very clever person, clever, isn't it?"
result=${text//clever/dumb}
echo "${result}"

Trim leading white-spaces

shopt -s extglob
output="    This is a test"
output="${output###*( )}"
shopt -u extglob
echo "${output}"

The command shopt -s extglob enables the extended pattern matching features of the bash, whereas the command shopt -u extglob disables it again.

Trim trailing whitespaces

shopt -s extglob
output="This is a test     "
output="${output%%*( )}"
shopt -u extglob
echo "${output}"

The command shopt -s extglob enables the extended pattern matching features of the bash, whereas the command shopt -u extglob disables it again.