Exit Status in Linux.

What is exit status in the linux?

Whenever you fire a shell command it returns a status to check if that command was successful or not – exit status can be very useful in scripts to make you scripts stable.

Example:-

In the example below, I ran uptime command and it was successful – so when I checked the exit status using echo $? it showed 0.

[root@server ~]# uptime
 05:15:27 up 50 days, 16:53,  1 user,  load average: 0.08, 0.03, 0.08

[root@server ~]# echo $?
0
[root@server ~]#

Now let’s see what happens when command is not successful.

So in the example below, I typed incorrect command and exit status was other than 0 – which indicates error.

[root@server ~]# uptimee
-bash: uptimee: command not found

[root@server ~]# echo $?
127
[root@server ~]#

Practical usage in shell scripting.

#!/bin/bash
cd $1 > /dev/null 2>&1

if [ $? != 0 ]
then
        echo "Directory Not Found" ; exit
fi

echo "Great!"

So, above script terminates if cd command is not successful.
If it’s successful it will execute further code.

[root@server ~]# ./exitstatus.sh /tmp
Great!

[root@server ~]# ./exitstatus.sh /tmpp
Directory Not Found
[root@server ~]#

Restart service automatically and get notified.

So you are running you own webserver which at the times is short of resources and the services like MySQL and HTTPD stops – results your website is down until you get a chance to fix it.

Quick solution would be to implement a script which restarts services at such situations and emails you that the service was restarted – so you can later go and check what was the problem

So below is the script, which will make sure that HTTP , MySQL and Postfix is running all the time – It will check status of the service and if it’s stopped or Dead it will restart it.

How to Implement this Script ?

Setup a cron to run the script every minute – like below.

* * * * * root /home/bob/scripts/servicecheck.sh

Create a file called servicecheck.sh and put the code below.
Just change the email address in the script to yours and you are done.

#!/bin/bash

#####################
#MySQL CHECK
#####################

/sbin/service mariadb status > /var/log/mysqlservicestatus 2>&1
STATUS=$(cat /var/log/mysqlservicestatus | egrep 'dead|failed')

        if [[ $STATUS = "" ]]
        then
/bin/logger -t MYSQL IS RUNNING
else
/sbin/service mariadb restart
/bin/logger -t restarted mysql
echo "Restarted MYSQL" | /bin/mail -s "Restarted MYSQL" you@email.com
fi
echo > /var/log/mysqlservicestatus

#####################
#HTTPD CHECK
#####################

/sbin/service httpd status > /var/log/httpdservicestatus 2>&1
STATUS=$(cat /var/log/httpdservicestatus | egrep 'dead|failed')

        if [[ $STATUS = "" ]]
        then
/bin/logger -t httpd IS RUNNING
else
/sbin/service httpd restart
/bin/logger -t restarted httpd
echo "Restarted HTTPD" | /bin/mail -s "Restarted HTTPD" you@email.com
fi

echo > /var/log/httpdservicestatus


#####################
#POSTFIX CHECK
#####################

/sbin/service postfix status > /var/log/postfixservicestatus 2>&1
STATUS=$(cat /var/log/postfixservicestatus | egrep 'dead|failed')

        if [[ $STATUS = "" ]]
        then
/bin/logger -t postfix IS RUNNING
else
/sbin/service postfix restart
/bin/logger -t restarted postfix
echo "Restarted postfix" | /bin/mail -s "Restarted postfix" you@email.com
fi

You want to monitor other services, just go ahead and add it.

How to use Array in Bash Scripting

First we will see what is Array in Linux

If you have been doing shell scripting, you must have definitely came across the term called variable. So when you use a variable, you can add a single name to the variable – In other words one variable can hold only one value.

Example of an Variable

#!/bin/bash
cityname="Berlin"
echo "$cityname"

So if you want to hold names of multiple cities, then you will have to create new variable for each city.

For an Example

cityname01="Berlin"
cityname02="Tokyo"
cityname03="Moscow"
cityname04="Rio"
cityname05="Denver"

However, to ease life we could use a single Array which could hold up all values in a single variable.

To define Array :-

cityname[0]="Berlin"
cityname[1]="Tokyo"
cityname[2]="Moscow"
cityname[3]="Rio"
cityname[4]="Denver"

So here we have stored all city Names in a Array called “cityname”. So now question is how do you access an Array.

You just need to echo it’s number 🙂 Like shown below.

#!/bin/bash
cityname[0]="Berlin"
cityname[1]="Tokyo"
cityname[2]="Moscow"
cityname[3]="Rio"
cityname[4]="Denver"
echo "${cityname[3]}"

So above script will print “Rio” If you want to print all city names then you would use

echo "${cityname[@]}"

OR

echo "${cityname[*]}"

You can copy paste the script below and run it which will help you understand better.

#!/bin/bash
cityname[0]="Berlin"
cityname[1]="Tokyo"
cityname[2]="Moscow"
cityname[3]="Rio"
cityname[4]="Denver"

echo Cities I love are : "${cityname[@]}"

Output would be.

Cities I love are : Berlin Tokyo Moscow Rio Denver

Shell Script to reboot multiple servers.

Here is simple bash script where you can add the server names in the command line and then it will go on rebooting every server which you have listed.

Script Usage:-

[root@server /]# ./server-reboot.sh appserver1 sqlserver1 dataserver1

Above command will reboot appserver1 sqlserver1 and dataserver1, if you have not setup ssh keys it will ask for password.

To use this script create a file called server-reboot.sh and following contents.

#!/bin/bash
for server in "${@}"
do
{
scriptName=$0
scriptPath=$(dirname $0)
script=$scriptPath/boot.txt
command=`base64 -w0 $script`
ssh -t $server "echo $command | base64 -d | sudo bash"
}
done

Create a another file named boot.txt in the same location where you have created server-reboot.sh.

for ((i=03; i>0; i--)); do sleep 1 ; printf "\rREBOOTING SERVER in $i Second. PRESS CTRL + C to cancel " ; done
shutdown -rf now

Save both the files, give execute permissions to server-reboot.sh and start rebooting.

It’s just not reboot script but you can add any commands which you want to run on multiple Linux servers in the file boot.txt

There are many other ways to do the same task but this works best for my environment. Add in comments what works best for you.