BASH Cheatsheet
Table of Contents
- About
- Cheats
- BASH Guard
- Stop Script Execution if Any Step Has An Error
- Get Absolute Path of Current Script
- Ensure Running as Root
- Heredoc Write To File
- Load Environment Variables From File
- Save Environment Variable To File For Loading Later
- Get Variable From User
- Ask User For Confirmation
- Store Commands In Variable
- String Concatenation Example
- Handling Arguments
- Ensure Number Of Expected Arguments
- Propagate Arguments
- Get File MD5
- Ensure A Directory Exists
- Ensure Running User Has Write Permission for a Directory
- Check If Variable Is Set
- Check If Variable is Empty
- Check If Variable Matches String
- Switch / Case Statement
- Lists (Arrays)
- Variable Variables
- Get Password From User
- Create Random Directory
- Colors
- Add to Cron (crontab)
- Time
- Networking
- References
About
Below are a set of "cheats" specific to programming BASH scripts. Since my default terminal uses BASH, I quite often confuse my commands with what should really be in the Linux CLI Cheatsheet, so if you can't find what your looking for here, please check that out as well.
Related Posts
Cheats
Bash Guard
Inject this into the top of your bash scripts to ensure that the script is running with in bash rather than sh. This is useful because bash and sh often require different syntax. It won't force the user to re-execute the script properly, but just re-execute itself as it was supposed to be done in the first place.
#!/bin/bash
if ! [ -n "$BASH_VERSION" ];then
echo "this is not bash, calling self with bash....";
SCRIPT=$(readlink -f "$0")
/bin/bash $SCRIPT
exit;
fi
# Put your code here
Stop Script Execution if Any Step Has An Error
The default shell behavior is to ignore errors in scripts. Placing the following line in your script will have the script stop if any step has an error. Read more
set -e
Get Absolute Path of Current Script
When writing scripts, I always like to use absolute references that are relative to the current file. This allows me to call the script from any directory, whilst also allowing me to pass that path to any other script working in any other directory as well. This is the same as using DIR in PHP. I also have a TCL equivalent.
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
This snippet was taken from a Stack Overflow post.
Ensure Running as Root
Inject this into the top of your bash scripts to ensure that the script is running with sudo or root permissions. This is useful if you need to ensure that once a script is started, it is never going to ask for a password on a "sudo" line if you have any.
USER=`whoami`
if [ "$USER" != "root" ]; then
echo "You need to run me with sudo!"
exit
fi
# Your script goes here....
Heredoc Write To File
If you need your BASH script to output some code to a file, then you may wish to make use of heredoc
cat << EOF > myScript.php
<?php
echo 'hello world' . PHP_EOL;
echo "Different quotes this time!" . PHP_EOL;
EOF
Load Environment Variables From File
source /path/to/settings/file.sh
Save Environment Variable To File For Loading Later
echo "export MY_VARIABLE=`echo $MY_VARIABLE`" > my-file.txt
Get Variable From User
echo -n "Enter your ____ and press [ENTER]: "
read MY_VARIABLE
echo $MY_VARIABLE
Ask User For Confirmation
read -p "Are you sure? " -n 1 -r
echo # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
# do dangerous stuff
fi
Store Commands In Variable
You can store commands as strings in variables and execute them later. However, to resolve issues with commands that have quotes, and for readability, it is best to use the eval command on that variable when you want to execute it. E.g.
CMD='echo "hello world"'
eval $CMD
Run the script below to demonstrate why you need to use eval
CMD='echo "hello world"'
echo -n "With eval: "
eval $CMD
echo -n "Without eval: "
$CMD
# Output
# With eval: hello world
# Without eval: "hello world"
String Concatenation Example
prefix="MyPrefix_"
DATETIME=`date +%Y_%m_%d_%H:%M:%S`
name="$prefix$DATETIME"
echo $name
Alternatively, in order to stick characters in between the variables, perform the following.
prefix="MyPrefix"
DATETIME=`date +%Y_%m_%d_%H:%M:%S`
name="`echo $prefix`_`echo $DATETIME`"
echo $name
Handling Arguments
The easiest way to explain this is to demonstrate with the following script:
#!/bin/bash
echo "you passed $# arguments to the script"
echo "They are: $@"
echo "The script is called $0 "
echo "the first argument is $1"
echo "the second argument is $2"
Below is the output I got when I ran it on /tmp/script.sh
you passed 0 arguments to the script
They are:
The script is called /tmp/script.sh
the first argument is
the second argument is
Ensure Number Of Expected Arguments
EXPECTED_NUM_ARGS=1;
if [ "$#" -ne $EXPECTED_NUM_ARGS ]; then
echo "Illegal number of aguments"
fi
Propagate Arguments
If you want to just pass all the arguments through to a subscript then use "$@"
. e.g
#!/bin/bash
/usr/bin/php /path/to/main.php "$@"
Get File MD5
md5sum [filepath]
Ensure A Directory Exists
DIRECTORY="/my/directory/path"
if ! [ -d $DIRECTORY ]; then
echo "$DIRECTORY does not exist!"
exit;
fi
Ensure Running User Has Write Permission for a Directory
if ! [ -w $DIRECTORY ] ; then
echo "You need to run this script with a user that has permission to write to $DIRECTORY" ;
exit;
fi
Check If Variable Is Set
If you want to check that a variable has been set and is not an empty string:
if [[ $MY_VARIABLE ]]; then
echo "MY_VARIABLE is $MY_VARIABLE";
fi
The following should work too:
if [ -n "$MY_VARIABLE" ]; then
echo "MY_VARIABLE is $MY_VARIABLE";
fi
Check If Variable is Empty
if [ -z "$EMPTY_STRING" ]; then
echo "That is an empty string";
fi
Check If Variable Matches String
if [ "$MY_VAR" == "something" ]; then
echo "That is an empty string";
fi
==
and [
]
as well as the quotation marks around "$MY_VAR"
are important!
Switch / Case Statement
Below is an example switch statement stolen from The Geek Stuff.
case "$1" in
1) echo "Sending SIGHUP signal"
kill -SIGHUP $2
;;
2) echo "Sending SIGINT signal"
kill -SIGINT $2
;;
3) echo "Sending SIGQUIT signal"
kill -SIGQUIT $2
;;
9) echo "Sending SIGKILL signal"
kill -SIGKILL $2
;;
*) echo "Signal number $1 is not processed"
;;
esac
Lists (Arrays)
You can create an array with one like like so:
MY_ARRAY=("item1" "item2")
Or you can spread it over multiple lines by continuously appending to the array:
MY_ARRAY=()
MY_ARRAY+=('foo')
MY_ARRAY+=('bar')
If one needs to create a BASH array from a PHP script's output, then one can do something like so:
$options = ['--bob', '--dick', '--harry', '--my multiword option'];
print(implode(PHP_EOL, $options));
... then on the BASH side:
declare -a MY_ARRAY
readarray -t MY_ARRAY <<< $(php dothis --autocomplete-help)
Variable Variables
I recommend avoiding variable variables, but they can be used in bash like so:
foo="something"
bar="foo"
echo ${!bar} # outputs "something"
Get Password From User
When getting a password from the user, you want to use stars to prevent others from seeing the inputs. However, because this is the case, you need to make sure they have to re-enter the password to ensure that they did not make a spelling mistake. At no point should you echo out the password.
function getPasswordFromUser()
{
while [ -z "$PASSWORD" ]
do
echo "Please enter a password:"
read -s PASSWORD1
echo "Please re-enter the password to confirm:"
read -s PASSWORD2
if [ "$PASSWORD1" = "$PASSWORD2" ]; then
PASSWORD=$PASSWORD1
else
# Output error message in red
red='\033[0;31m'
NC='\033[0m' # No Color
echo ""
echo -e "${red}Passwords did not match!${NC}"
fi
done
}
# This works because there is no scope in the function
# any variables defined within it are defined outside it
getPasswordFromUser;
echo "your password is $PASSWORD"
Create Random Directory
The following command will create a randomly named temporary directory in /tmp, and store the name a variable called RANDOM_DIR
. You may need this in your scripts if they need to do something like download and then install a deb file.
RANDOM_DIR=`mktemp -d`
Here are some other useful uses of mktemp
.
# Dont store the name, just switch
# to the dir after creating it
cd $(mktemp -d)
# Create a temporary directory with a provided prefix
mktemp -d -t [prefix for directory]
Colors
You can use echo -e
to output text with color. However you will need to look up the relevant color codes which can be found here.
For example:
echo -e "Default \e[95mLight magenta"
Add to Cron (crontab)
Often it's necessary for an installation script to install a cron job, such as to run a script on boot. To do this automatically, just use the following code snippet. Make sure to adjust the third line accordingly.
TMP_CRON_FILE="/tmp/cron_file"
crontab -l > $TMP_CRON_FILE
echo "@reboot /bin/bash /path/to/bash/script.sh" >> $TMP_CRON_FILE
crontab $TMP_CRON_FILE
rm $TMP_CRON_FILE
Time
Unix Timestamp
TIMESTAMP=`date +%s`
Date Variable
DATE=`date +%Y_%m_%d`
Time Variable
TIME=`date +%H:%M:%S`
Date-Time Variable
DATETIME=$(date "+%d-%m-%Y %H:%M:%S") # 18-03-2022 13:40:05
DATETIME=`date +%Y_%m_%d_%H:%M:%S` # 2022_03_18_13:41:10
Networking
Automatically Assign Network Interface To Variable
This is a modified version that came from here.
NETWORK_INTERFACE=`ip link | awk -F: '$0 !~ "lo|vir|veth|docker|br-|wl|^[^0-9]"{print $2;getline}'`
Assign Interface's IP to Variable
INTERFACE="enp7s0"
SERVER_IP=$(ip --json addr show $INTERFACE | jq -r '.[0].addr_info[] | select(.family == "inet") | .local')
jq
packgage installed.
Below is an alternative version that is based on servers that have the ifconfig
command.
INTERFACE="eth0"
SERVER_IP=$(ifconfig $INTERFACE | grep "inet addr" | awk '{print $2;}' | cut -d : -f 2)
$OUTBOUND_INTERFACE
to be venet0:0
.
Assign Internet IP to Variable
The line below will assign your IP as it appears to others on the internet, to a variable.
SERVER_IP=$(curl --silent ifconfig.me)
curl
installed.
References
- Stack Overflow - How to check if a directory exists in a shell script
- Stack Overflow - How do I prompt a user for confirmation in bash script? [duplicate]
- Stack Overflow - Bash: add value to array without specifying a key
- Stack Overflow - Bash - variable variables
- Stack Overflow - How to change the output color of echo in Linux
- Stack Overflow - How can I write a here doc to a file in Bash script?
- Serverfault - How to determine if a bash variable is empty?
- Stack Overflow - How to create a temporary directory?
- Stack Overflow - Propagate all arguments in a bash shell script
- phoenixnap.com - Bash HereDoc Tutorial With Examples
First published: 16th August 2018