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

我有一个方法的
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

即使刚刚启动过程,这些解决方案也无法正常工作并退出.

最佳答案 .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身份运行,这意味着进程正在使用相同的用户标识运行).

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

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

点赞