Shell Script to Check Linux System Health

This article we are introducing a shell script to perform linux system health check. This script collects system information and status like hostname, kernel version, uptime, cpu / memory / disk usage. Script uses hostname, uptime, who, mpstat, lscpu, ps, top, df, free, bc commands to get system information and cut, grep, awk and sed for text processing. The output of the script is a text file which will be generated in the current directory. A variable is set to provide email address to which script can send report file. Apart from system status, the script will check a predefined threshold for cpu load and filesystem size.

Remember : Make sure you have all the above commands working, to output all results correctly.

Understanding linuxhealthcheck.sh Script

#tell which shell to use
#!/bin/bash
#Here we put email address to send email with report. If no email provided – log file will be just saved.
EMAIL='[email protected]'
#We will create function to easily manage what to do with output.
function sysstat {

#uptime command used to get uptime, and with sed command we cat process output to get only uptime.
Uptime : `uptime | sed 's/.*up \([^,]*\), .*/\1/'`

#who command is used to get last reboot time, awk for processing output
Last Reboot Time : `who -b | awk '{print $3,$4}'`

*********************************************************************

CPU Load - > Threshold < 1 Normal > 1 Caution , > 2 Unhealthy

*********************************************************************

"

#here we check if mpstat command is in our system
MPSTAT=`which mpstat`

#here we get exit code from previous command
MPSTAT=$?

#if exit status in not 0, this means that mpstat command is not found (or not exist in our system)
if [ $MPSTAT != 0 ]

then

echo "Please install mpstat!"

echo "On Debian based systems:"

echo "sudo apt-get install sysstat"

echo "On RHEL based systems:"

echo "yum install sysstat"

else

echo -e ""

#here we check in same way if lscpu installed
LSCPU=`which lscpu`

LSCPU=$?

if [ $LSCPU != 0 ]

then

RESULT=$RESULT" lscpu required to procedure accurate results"

else

#if we have lscpu installed, we can get number of CPU's on our system and get statistic for each using mpstat command.
cpus=`lscpu | grep -e "^CPU(s):" | cut -f2 -d: | awk '{print $1}'`

i=0

#here we make loop to get and print CPU usage statistic for each CPU.
while [ $i -lt $cpus ]

do

#here we get statistic for CPU and print it. Awk command help to do this, since output doesn't allow this to do with grep. AWK check if third value is equal to variable $i (it changes from 0 to number of CPU), and print %usr value for this CPU
echo "CPU$i : `mpstat -P ALL | awk -v var=$i '{ if ($3 == var ) print $4 }' `"

#with ps command we get list of processes, awk show only needed columns. After with sort command we sort it by third column and we need only top 10, that why we used head command
`ps aux | awk '{print $2, $4, $6, $11}' | sort -k3rn | head -n 10`

Top CPU using process/application

#with top command we get top CPU using processes, and with combination of head and tail we get top 10.
`top b -n1 | head -17 | tail -11`

"
#we get disk usage with df command. -P key used to have postfix like output (there was problems with network shares, etc and -P resolve this problems). We print output to temp file to work with info more than one.
df -Pkh | grep -v 'Filesystem' > /tmp/df.status

#We create loop to process line by line from df.status
while read DISK

do

#here we get line from df.status and print result formatted with awk command
LINE=`echo $DISK | awk '{print $1,"\t",$6,"\t",$5," used","\t",$4," free space"}'`

echo -e $LINE

echo

done < /tmp/df.status

echo -e "

Heath Status"

echo

#here almost same loop, but we check disk usage, and print Normal if value less 90, Caution if between 90 and 95, and Unhealthy if greater than 95)
while read DISK

do

USAGE=`echo $DISK | awk '{print $5}' | cut -f1 -d%`

if [ $USAGE -ge 95 ]

then

STATUS='Unhealthy'

elif [ $USAGE -ge 90 ]

then

STATUS='Caution'

else

STATUS='Normal'

fi

LINE=`echo $DISK | awk '{print $1,"\t",$6}'`

#here we print result with status
echo -ne $LINE "\t\t" $STATUS

echo

done < /tmp/df.status

#here we remove df.status file
rm /tmp/df.status

#here we get Total Memory, Used Memory, Free Memory, Used Swap and Free Swap values and save them to variables.
TOTALMEM=`free -m | head -2 | tail -1| awk '{print $2}'`
#All variables like this is used to store values as float (we are using bc to make all mathematics operations, since without bc all values will be integer). Also we use if to add zero before value, if value less than 1024, and result of dividing will be less than 1.
TOTALBC=`echo "scale=2;if($TOTALMEM 0) print 0;$TOTALMEM/1024"| bc -l`
USEDMEM=`free -m | head -2 | tail -1| awk '{print $3}'`
USEDBC=`echo "scale=2;if($USEDMEM 0) print 0;$USEDMEM/1024"|bc -l`
FREEMEM=`free -m | head -2 | tail -1| awk '{print $4}'`
FREEBC=`echo "scale=2;if($FREEMEM 0) print 0;$FREEMEM/1024"|bc -l`

#if email proviced – we check if we have mailx command to send email
STATUS=`which mail`
#if mailx command not exist on system (previous command returned non-zero exit code we warn user that mailx is not installed
if [ "$?" != 0 ]

SHARE ON

Hand-picked related articles

Regular backup of mysql databases are also as important as backing up your code. So I wrote this script to backup all of my databases on local disk. I then added gzip to compress the sql file to save disk [...]

This script is very useful if a user needs to quickly clean up space and it helps to check which directories take most of space and the delete according to your wish. Below shell script shows X number of directories that [...]

How to make automation with bash for loop under Linux/UNIX operating system? How do I use break, continue and the parameter for loop control expression? How to act on files using for loop? For loop is a very useful tool [...]

Your script works in some condifitions and a specific hardware environment. We must review your script between the lines 83-87, because temporary files are misinterpreted and impacted by the hardware environment on which Linux System running. Today web servers are equipped with hard drives "SSD". SWAP partitions do not like SSD.
Best Regards

I'm having an problem getting the result i need in the Memory portion. Everytime i run i the below error occurs.

[[email protected] ~]# ./linuxhealthcheck.sh
./linuxhealthcheck.sh: line 99: bc: command not found
./linuxhealthcheck.sh: line 101: bc: command not found
./linuxhealthcheck.sh: line 103: bc: command not found
./linuxhealthcheck.sh: line 105: bc: command not found
./linuxhealthcheck.sh: line 107: bc: command not found
./linuxhealthcheck.sh: line 109: bc: command not found

in Health Status uptime return the value for a single core, in a multicore environment you should change this script considering that. For example in a 32 core env the Unhealty state will be only if $1 > 64 Caution with $1 > 32 and so on.

[email protected]:~$ ./linuxhealthcheck.sh
Reported file health-uamicrweb1-161130-1425.txt generated in current directory.
./linuxhealthcheck.sh: line 134: [email protected]: command not found
The program 'mail' is currently not installed.[email protected]:~$ mail
Cannot open mailbox /var/mail/microsecadmin: Permission denied
No mail for microsecadmin[email protected]:~$ sudo mail
No mail for root