检查进程是否正在运行,如果进程已在运行,则退出

时间:2016-07-01 02:37:37

标签: bash shell scripting scripting-language

我有一个带有方法的shell脚本:

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

我正在使用此命令运行此脚本:./script.sh start以调用start方法。现在,我想检查此进程是否已在运行,如果已在运行,则退出。我在网上尝试了一些解决方案但没有任何效果有人请帮忙。 我尝试的解决方案是:

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

另一个是:

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

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

这些解决方案无法正常工作,即使刚刚启动该流程也会退出。

2 个答案:

答案 0 :(得分:1)

.lock文件解决方案应该有效。唯一的问题是如果脚本由于错误而退出,并且不会删除锁定文件。改进是将进程的PID存储在文件中,并检查该PID是否仍然存在。

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实际上并不向进程发送信号,只是测试是否可以发送信号:PID存在并且您有权向其发送信号(除非您以root身份运行) ,这意味着该进程使用相同的用户ID运行。

如果脚本崩溃然后其PID被同一用户重用,那么这可能会产生误报。但是PID重用应该花费很长时间,并且它被同一用户重用的可能性应该很低。

还有可能同时启动两个脚本副本,并且他们都会看到没有锁定文件。如果需要防范,则应使用lockfile命令在检查文件的代码周围实现互斥。

答案 1 :(得分:1)

这里我的脚本希望有用。

#!/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