Ultimate Bash Guide For Beginners

bashEveryone who is new to scripting always doesn’t know where to start. There’s countless websites and blog posts out there with endless number of commands and bash guides. I don’t want to share all those super complex commands which are difficult to understand when you first start out with writing some scripts. Instead, I am providing a short bash guide for beginners. This post will cover the basics, some good manners and some more advanced commands.

One of the reasons why I started to write scripts in bash is because bash was just the language I knew due to Linux distros. However, I’m by no means an expert in writing scripts. If someone would ask me about my level of expertise in this area, I would rate myself with a “C”, maybe a C+.

Even though I am not an expert, I think it will be useful to share my experience and the commands which I have used most often. Below some general tips and commands which have helped me in the past and I still sue every day for some basic scripting.

General tips and tricks

Use clear and precise comments.
This will allow other users to easily read and understand your code.

#Validates that the variable is not an empty string. If it is an empty string it will set it false.
if [ -n "my-var" ]; then
    echo "Variable is not empty"
else 
    echo "Variable is empty"
fi

User proper indention
Indention will make your code easier readable. If your code is easily readable, it will be even easier to maintain it in the future.

if [ -n "$my-var" ]; then
    echo "Variable is not empty"
else 
    echo "Variable is empty"
fi

Let your script bail out if any command fails
For debugging of your script, you should use set -e at the beginning of your script.
Using set -e ensures that your script exists as soon as any of the lines is failing.

#!/bin/bash
set -e

Every bash script has to start with it
The first line in every bash script has to be #!/bin/bash
This will tell your terminal which interpreter to run.

Common Commands

Declare a timestamp function
For all my scripts I declare a function which stores the current timestamp when it is called.
I mainly use the timestamp variable for logging of events.

#!/bin/bash

timestamp() {
 date +"%Y-%m-%d_%T"
}

echo $(timestamp): "My script starts here"

a=5
b=6

if [ "$a" -gt "$b" ]; then
    echo $(timestamp): $a "is bigger than" $b
else
    echo $(timestamp): $b "is smaller than" $a
fi

The output will look like this:

./bs.sh
2015-04-15_22:06:55: My script starts here
2015-04-15_22:06:55: 6 is smaller than 5

Use $? to check the previous command
You can use $? to verify whether the previous commands returned 0 or 1.
0 = successful | 1 = failed

#!/bin/bash

timestamp() {
 date +"%Y-%m-%d_%T"
}

touch /tmp/test.log

if [ $? -eq 0 ]; then
    echo $(timestamp) "/tmp/test.log has successfully been created"
else 
    echo $(timestamp) "/tmp/test.log has not been created"
fi

If the script was able to create the file it will return:

./bs.sh
2015-04-15_22:14:04 /tmp/test.log has successfully been created

Read a file with comma separated values and act on it
When querying a database and saving the results as a CSV file, each results will be stored in a line and each value will be comma separated. Below is s simple script which scans a CSV file for the 4th value in every line and prints it, if it is not empty.

#!/bin/bash
timestamp() {
 date +"%Y-%m-%d_%T"
}

#This script expects a CSV file, called test.csv, in /tmp.

#This will read line by line till the end of the file

while read line; do 
#Echo $line, one line after the other, use "cut -d, -f 4" to look for values which are separated by "," and store the value in field "4" as $training

training="$(echo $line | cut -d, -f 4)"

#If $training is not empty, print $training

if [ -n "$training" ]; then
    echo $(timestamp): $training
else
#If $training is empty, print the line below 
    echo $(timestamp): "Field 4 was empty in file /tmp/test.csv"; fi; done < /tmp/test.csv

How To Backup osTicket?

A friend of mine is using osTicket for his small support team and was wondering how he could backup osTicket. I did some online search and expected to find thousands of threads and hundreds of scripts.

Lot’s of people suggested to use mysqldump and backup your webserver but I couldn’t find a quick an easy script, which would help my friend.

I create a basic bash script which you can add to a cronjob to make sure it will regularly backup your system.

osticket_backup_script

 The following of the script needs to be modified with your settings:

######################################
###########Configure variables########
######################################

#Specify mysqlserver server dns name or IP
mysqlserver='DB_SERVER'

#Specify username for database
mysqluser='DB_USER'

#Specify password for database
mysqlpasswd='DB_PASSWD'

#Specify database name
mysqldb='OSTICKET_DB'

#Specify email address for email notifications
email='[email protected]'

#Used to, temporary, store the mysqldump & osTicket config file
tmpdir='/backup/tmp'

#Specify where the local backup copy will be stored
backupdir='/backup/'

#Specify name of the mysqldump
dbfile="DB-backup-$date.dump"

#Specify path to osTicket config file
config='/srv/www/htdocs/include/ost-config.php'

#Specify name and location of backup file
backupfile="/backup/backup-$date.tar"

#Specify number of local backup copies to keep
local_copy='28'

#Specify number of remote backup copies to keep
remote_copy='56'

#Specify your remote server (needs SSH enabled)
remote_server='MY_REMOTE_SERVER'

#Specify username for remote server
remote_user='MY_REMOTE_USER'

The backup.log is very easy to ready and a successful backup will look like this:

###########################################
############Backup started#################
###########################################
2015-03-04_12:00:02: Start DB Backup
2015-03-04_12:00:02: Finished DB backup
2015-03-04_12:00:02: Start config backup
2015-03-04_12:00:02: Finished config backup
2015-03-04_12:00:02: List of /backup/tmp conent:
DB-backup-2015-03-04_12-00-02.dump, ost-config.php
2015-03-04_12:00:02: Start tar all backup files
2015-03-04_12:00:02: Finished tar all backup files
2015-03-04_12:00:02: Start cleaning all files in tmpdir, list of files, shown below:
DB-backup-2015-03-04_12-00-02.dump, ost-config.php
2015-03-04_12:00:02: Finished clean-up of all files in tmpdir
2015-03-04_12:00:02: List of files which have not been delete

2015-03-04_12:00:02: Start copy of /backup/backup-2015-03-04_12-00-02.tar to remote location
2015-03-04_12:00:02: Finished copy to remote location
2015-03-04_12:00:02: Changed directory to /backup/
2015-03-04_12:00:02: Start to delete old local backups - keep only 28
2015-03-04_12:00:02: Finished cleanup of local backups
2015-03-04_12:00:03: Start to delete old remote backups - keep only 56
2015-03-04_12:00:03: Finished cleanup of remote backups
###########################################
############Backup was successful##########
###########################################

How to restore from my backups?

  1. Untar backup file
    1. tar -zxvf backup_file.tar
  2. Restore your DB_file.dump
    1. mysql -u root -p[root_password] database_name < DB_file.dump
  3. Restore your ost-config.php
    1. cp ost-config.php /srv/www/htdocs/include/ (or to wherever osTicket is installed)

Refresh your browser and you should be able to see all your restored data.

If you have any feature requests or bugs, please do not hesitate yo reach out to me. My contact details are in the script header.