Linux Script to check if process is running and act on the result
Solution 1
Programs to monitor if a process on a system is running.
Script is stored in crontab
and runs once every minute.
This works with if process is not running or process is running multiple times:
#! /bin/bash
case "$(pidof amadeus.x86 | wc -w)" in
0) echo "Restarting Amadeus: $(date)" >> /var/log/amadeus.txt
/etc/amadeus/amadeus.x86 &
;;
1) # all ok
;;
*) echo "Removed double Amadeus: $(date)" >> /var/log/amadeus.txt
kill $(pidof amadeus.x86 | awk '{print $1}')
;;
esac
0
If process is not found, restart it.
1
If process is found, all ok.
*
If process running 2 or more, kill the last.
A simpler version. This just test if process is running, and if not restart it.
It just tests the exit flag $?
from the pidof
program. It will be 0
of process is running and 1
if not.
#!/bin/bash
pidof amadeus.x86 >/dev/null
if [[ $? -ne 0 ]] ; then
echo "Restarting Amadeus: $(date)" >> /var/log/amadeus.txt
/etc/amadeus/amadeus.x86 &
fi
And at last, a one liner
pidof amadeus.x86 >/dev/null ; [[ $? -ne 0 ]] && echo "Restarting Amadeus: $(date)" >> /var/log/amadeus.txt && /etc/amadeus/amadeus.x86 &
This can then be used in crontab to run every minute like this:
* * * * * pidof amadeus.x86 >/dev/null ; [[ $? -ne 0 ]] && echo "Restarting Amadeus: $(date)" >> /var/log/amadeus.txt && /etc/amadeus/amadeus.x86 &
cccam oscam
Solution 2
I adopted the @Jotne solution and works perfectly! For example for mongodb server in my NAS
#! /bin/bash
case "$(pidof mongod | wc -w)" in
0) echo "Restarting mongod:"
mongod --config mongodb.conf
;;
1) echo "mongod already running"
;;
esac
Solution 3
I have adopted your script for my situation Jotne.
#! /bin/bash
logfile="/var/oscamlog/oscam1check.log"
case "$(pidof oscam1 | wc -w)" in
0) echo "oscam1 not running, restarting oscam1: $(date)" >> $logfile
/usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1 &
;;
2) echo "oscam1 running, all OK: $(date)" >> $logfile
;;
*) echo "multiple instances of oscam1 running. Stopping & restarting oscam1: $(date)" >> $logfile
kill $(pidof oscam1 | awk '{print $1}')
;;
esac
While I was testing, I ran into a problem..
I started 3 extra process's of oscam1 with this line:
/usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1
which left me with 8 process for oscam1. the problem is this..
When I run the script, It only kills 2 process's at a time, so I would have to run it 3 times to get it down to 2 process..
Other than killall -9 oscam1
followed by /usr/local/bin/oscam1 -b -c /usr/local/etc/oscam1 -t /usr/local/tmp.oscam1
, in *)
is there any better way to killall apart from the original process? So there would be zero downtime?
linuxnoob
Updated on July 09, 2022Comments
-
linuxnoob almost 2 years
I have a process that fails regularly & sometimes starts duplicate instances..
When I run:
ps x |grep -v grep |grep -c "processname"
I will get:2
This is normal as the process runs with a recovery process..If I get
0
I will want to start the process if I get:4
I will want to stop & restart the processWhat I need is a way of taking the result of
ps x |grep -v grep |grep -c "processname"
Then setup a simple 3 option function
ps x |grep -v grep |grep -c "processname" if answer = 0 (start process & write NOK & Time to log /var/processlog/check) if answer = 2 (Do nothing & write OK & time to log /var/processlog/check) if answer = 4 (stot & restart the process & write NOK & Time to log /var/processlog/check)
The process is stopped with
killall -9 process
The process is started withprocess -b -c /usr/local/etc
My main problem is finding a way to act on the result of
ps x |grep -v grep |grep -c "processname"
.Ideally, I would like to make the result of that grep a variable within the script with something like this:
process=$(ps x |grep -v grep |grep -c "processname")
If possible.
-
linuxnoob over 10 yearsOK, I will test this and report back, The wild card might be usefull also in my case because there could be (3,5,6,7...) process's running and all of those results would be a problem. Will the * in your script mean all instances of the process other than 1 or 2?
-
Jotne over 10 yearsYes, corrected my comment to reflect that. You should also try to use
pidof
instead ofps
-
hek2mgl over 10 yearsI think you should additionally check who is the owner of the process
-
Jotne over 10 yearsNot needed, since for this there always would be one owner and one process.
-
Pipetus over 7 yearsVery nice! Not sure if it's suitable for you, but depending on what linux you're working with, you might have specific tools to achieve a nice process monitoring (for instance,
procd
for OpenWRT,daemontools
, etc.) -
tripleee over 6 yearsThe
command; if [[ $? -ne 0 ]]
is an antipattern. The purpose ofif
and the shell's other flow control statements is to run a command and check its return code. The proper and idiomatic way to write that isif ! command
(though the negation may not work in really old versions of the Bourne shell; just invert thethen
andelse
cases to be portable back into the late 1970s. However, of course,[[
isn't Bourne-compatible anyway; so if you are targeting Bash specifically, this is not a concern anyhow).