Linux Script to check if process is running and act on the result

121,364

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?

Share:
121,364
linuxnoob
Author by

linuxnoob

Updated on July 09, 2022

Comments

  • linuxnoob
    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 process

    What 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 with process -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
    linuxnoob over 10 years
    OK, 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
    Jotne over 10 years
    Yes, corrected my comment to reflect that. You should also try to use pidof instead of ps
  • hek2mgl
    hek2mgl over 10 years
    I think you should additionally check who is the owner of the process
  • Jotne
    Jotne over 10 years
    Not needed, since for this there always would be one owner and one process.
  • Pipetus
    Pipetus over 7 years
    Very 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
    tripleee over 6 years
    The command; if [[ $? -ne 0 ]] is an antipattern. The purpose of if 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 is if ! command (though the negation may not work in really old versions of the Bourne shell; just invert the then and else 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).