Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a process is running and exit if it is already running

I have a shell script with methods:

start(){
echo "Hello world"
}

stop(){
ps -ef|grep script.sh|grep -v grep|xargs kill
}

while [ "$1" != "" ]; do
case "$1" in
        start)
            start
            ;;
        stop)
            stop
            ;;
        *)
            echo $"Usage: $0 {start|stop}"
            exit 1
        esac
   shift
done

I am running this script using this command: ./script.sh start to call the start method.Now, I want to check if this process is already running and exit if it is already running. I have tried some solutions online but nothing worked. Someone please help. The solutions I have tried were:

if [ -f /var/tmp/script.lock ]; then
  echo "Already running. Exiting."
  exit 1
else
  touch /var/tmp/script.lock
fi
<main script code>
#some code
rm /var/tmp/script.lock

The other one is:

PID=$(ps -ef | grep script.sh|grep -v grep)

   if [ -z $PID ]; then
       echo "Process already running"
       exit   
fi

These solutions doesn't work and exit even when the process is just started.

like image 627
user6348718 Avatar asked Jul 01 '16 02:07

user6348718


2 Answers

The .lock file solution should work. The only problem with it is if the script exits due to an error, and doesn't remove the lock file. An improvement is to store the PID of the process in the file, and check whether that PID still exists.

if [ -f /var/tmp/script.lock ] && kill -0 $(cat /var/tmp/script.lock); then
  echo "Already running. Exiting."
  exit 1
else
  echo $$ > /var/tmp/script.lock
fi
<main script code>
#some code
rm /var/tmp/script.lock

kill -0 doesn't actually send a signal to the process, it just tests whether it's possible to send a signal: the PID exists and you have permission to send signals to it (unless you're running as root, this means the process is running with your same userid).

There's still a remote chance that this could get a false positive, if the script crashes and then its PID gets reused by the same user. But PID reuse should take a long time, and the chance that it gets reused by the same user should be low.

There's also the chance that two copies of the script will start simultaneously, and they'll both see that there's no lock file. If you need to protect against that, you should use the lockfile command to implement a mutex around the code that checks for the file.

like image 173
Barmar Avatar answered Sep 23 '22 10:09

Barmar


Here my script hope useful.

#!/bin/bash
export JAVA_HOME=/usr/java/jdk1.7.0_25

checkpid()
{
        echo $(ps -ef | grep "LiquidityWarning.jar" | grep -v grep | awk '{ print $2}')
}

start ()
{
    if [ $(checkpid) ] ; then
        echo -e "\n$(date +%Y%m%d-%H:%M:%S) LiquidityWarning.jar is running (pid:$(checkpid))\n"
    else
        echo ""
        printf "$(date +%Y%m%d-%H:%M:%S) LiquidityWarning.jar is starting..."
        cd /app/mservice/CBTK_new
        /usr/java/jdk1.7.0_25/bin/java -jar LiquidityWarning.jar > /dev/null 2>&1 &

    fi

}

stop ()
{
    if [ $(checkpid) ] ; then
        kill -9 $(checkpid)
        echo -e "\n$(date +%Y%m%d-%H:%M:%S) LiquidityWarning.jar stop success\n"
    fi

}

status ()
{
        if [ $(checkpid) ] ; then
        echo -e "\n$(date +%Y%m%d-%H:%M:%S) LiquidityWarning.jar is running (pid:$(checkpid))\n"
    else    
        echo -e "\n$(date +%Y%m%d-%H:%M:%S) LiquidityWarning.jar is not started\n"
    fi
}

restart()
{
        if [ $(checkpid) ] ; then
                stop
                sleep 2
                start
        else
                echo -e "\n$(date +%Y%m%d-%H:%M:%S) LiquidityWarning.jar is not started\n"
        fi
}

case "$1" in
  start)
      start
      ;;
  stop)
      stop
      ;;
  restart)
      restart
      ;;
  status)
      status
      ;;
  *)
    echo -e "\nUsage: $0 {start|stop|status|restart|reload}\n"
      exit 1
      ;;
esac
like image 26
Bình Nguyễn Quang Avatar answered Sep 19 '22 10:09

Bình Nguyễn Quang