我有一个cron作业,它调用一个脚本,该脚本每小时检查一次更新。如果有更新,它将调用update.sh
,然后调用commands.sh
。我希望每个“new”commands.sh
只运行一次。
每次运行带有该文件的某个唯一id的commands.sh
时,我都在考虑写入该文件。在运行commands.sh
之前,我检查文件是否包含commands.sh
的id。如果是,不要运行它。
编辑-更多详细信息:
cronjob:
从git repo获取,如果有任何更改,则拉取并合并
运行update.sh
:
#!/bin/sh
./commands.sh
我希望
./commands.sh
只运行一次,因为下个小时,cron将再次运行,从git中提取,然后再次运行update.sh
。有没有办法让每个独特的./commands.sh
只运行一次?写出来之后,如果git repo有变化,最好的方法可能是只运行
update.sh
?这似乎是杀伤力过大,难以维持。有没有更简单的方法来编写只运行一次的bash脚本?
最佳答案
在commands.sh
脚本开始时,请执行以下操作:
if [ -f stampfile ]; then
exit
if
touch stampfile
这将检查名为
stampfile
的文件(指定存储该文件的任何方便位置的路径)。如果它在那里,只要exit
。如果不存在,则使用touch
创建它。那就让剧本来做吧。
有点离题:这也可以用来避免同时运行两个脚本实例。脚本将在运行结束时
rm -f stampfile
。在这种情况下,如果脚本被终止,
stampfile
将是“过时的”(存在标记,但脚本不活动)。要检测过时的stampfile
,请将脚本的pid放入其中,而不是触摸它。要检查是否有另一个实例正在运行,并管理stampfile:
if [ -f stampfile ]; then
if kill -0 $(<stampfile) 2>/dev/null; then
exit
else
rm -f stampfile # stale
fi
fi
echo $$ >stampfile
# rest of script
rm -f stampfile
user@charlesduffy指出,这种管理
stampfile
的方法可能容易出现pid重用问题,即过时的stampfile
中的pid可能是一个正在运行的进程的pid,与这些无关。显然有a Linux utility called flock
可以让你以一种更稳健的方式来做这件事。