我有一个每分钟运行一次的 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}