BASH Cheatsheet
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
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....
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
Auatomatically Assign Network Interface To Variable
This came from here.
NETWORK_INTERFACE=`ip link | awk -F: '$0 !~ "lo|vir|wl|^[^0-9]"{print $2;getline}'`
Store Commands In Variables
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"
Unix Timestamp
TIMESTAMP=`date +%s`
Date Variable
DATE=`date +%Y_%m_%d`
Time Variable
TIME=`date +%H:%M:%S`
Date-Time Variable
DATETIME=`date +%Y_%m_%d_%H:%M:%S`
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
Assign IP to Variable
OUTBOUND_INTERFACE="eth0"
SERVER_IP=$(ifconfig $OUTBOUND_INTERFACE | grep "inet addr" | awk '{print $2;}' | cut -d : -f 2)
$OUTBOUND_INTERFACE
to be venet0:0
.
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
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')
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"
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')
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
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
First published: 16th August 2018