我需要让我的脚本在给定时间内只运行一次。
等式:- 第一次脚本将在 9:30 运行,但如果有人尝试在 930 到 945 之间再次运行我的脚本(例如手动或通过作业在 940 运行),则它不应运行。
if [ (${date} -gt "0930" && ${date} -lt "0945") or (${date} -gt "1130" && ${date} -lt "1145") ]
then
write_log "Fetching data"
while read line
do
"does processing"
done < ${CONFIG_FILE}
else
write_log "Its not time to fetch details."
fi
答案1
您可以将上次运行日期保存在文件中:
date +"%s" > last_file
last_file
这里是文件名。这会写入自纪元开始以来的秒数,例如。 1549605438。一旦你有了这个,你可以阅读它:
read last < last_file
这last
是一个 shell 变量名。一旦你有了这个,你需要一些算术来进行比较:
threshold=900 # 60 * 15 = 15 minutes
[ "$(date +'%s')" -gt "$((last + threshold))" ] || exit
将现在的第二个计数与最后一个计数加上设置的暂停间隔进行比较。如果还没有足够的时间,请退出。否则继续——执行脚本的其余部分。
最后,您需要一些信号量来防止两个实例以相同的方式启动,即。进程 2 在进程 1 检查上次运行日期并编写自己的日期之前启动。
完整的算法如下所示:
- 设置信号量。
- 读取上次运行时间。
- 如果你有绿灯,请编写你自己的运行时间(可能稍后,一旦你正确完成操作)。
- 做这个脚本所涉及的事情。
- 释放信号量。
您需要记住,在第一次运行脚本之前,last_file
除非您手动将其放置在那里,否则它将不存在。因此,要么将其放置在那里,要么通过适当的逻辑使您的脚本免受此影响。
答案2
在脚本末尾,您可以用来date +%s
获取当前时间(自 1970 年 1 月 1 日起以秒为单位)并将其写入外部文件,覆盖现有内容。
在脚本开始时,您可以从文件中读取该值,获取当前时间(再次使用date +%s
),从另一个中减去一个,然后使用差值来决定要做什么。
(这就是大局。显然,您必须处理诸如找不到文件、读取非数字值、文件权限、竞争条件等情况。但这些都是细节。)