检查进程是否正在运行,即使在 cron 下

检查进程是否正在运行,即使在 cron 下

我有一个每分钟运行一次的 cron 作业,但如果它发现数据,可能需要几分钟才能完成。

我需要判断脚本的另一个实例是否正在运行。为了让事情变得更有趣,我们调用同一个脚本,但使用不同的参数。例如:

* * * * * /home/user/script.sh Dir1 > /tmp/logdir1.log
* * * * * /home/user/script.sh Dir2 > /tmp/logdir2.log

我曾经测试过这样的事情:

FORMAT="`basename $0` $1"
OLDPID=`pgrep -f -o "${FORMAT}"`  #grab the oldest copy of the PID matching this format
echo $OLDPID:$$ 
If [ "$OLDPID" -eq "$$" ]

....

在我的测试中,这很有效,如果最旧的 PID 与当前 PID 不同,则有另一个正在运行。但是,从 cron 运行时,该进程出现两次,因此最旧的 pid 不是当前的 pid:

user 1094 0.0 0.0 8720 944 ? Ss 12:38   0:00      \_ /bin/sh -c /home/user/script.sh Dir1 > /tmp/logdir1.log
user 1097 0.1 0.0 8856 1236 ?  S 12:38   0:00          \_ /bin/bash /home/user/script.sh Dir1

所以我的脚本每次都会失败,因为它看到重复。有没有办法告诉 pgrep 忽略第一个?

过去,我们在读取 pidfile 然后查看该进程是否仍在运行时遇到了一些问题。(其他进程获得相同的 pid,并且不同版本的 centos 似乎具有略微不同的 PS 参数)

您将如何解决这个问题?

答案1

按照说明使用 flock重叠作业 - 锁

答案2

做这样的事:

#!/bin/bash

pidfile=/var/run/myscript.pid

if [ -f ${pidfile} ]; then # is there already a  pid file?
  oldpid=$(cat ${pidfile})
  ps -p ${oldpid} &> /dev/null # is the process still running?
  if [ $? -ne 0 ]; then
    rm ${pidfile} # pid file is stale, remove it
  else
    echo "Old process still running"
    exit 1
  fi
fi

echo $$ > ${pidfile}

# DO STUFF

rm ${pidfile}

相关内容