睡到下次特定时间


11

我需要一系列命令或一个可以休眠的命令,直到下一次出现“ 4:00”之类的特定时间为止。

我该怎么办?

at命令或cronjob是不可选项,因为我一定不要离开当前所在的脚本。

我正在谈论的特定情况是在屏幕上运行的脚本。我不要停止脚本本身来执行脚本,这一点非常重要,因为在脚本的某些地方需要存储许多重要的变量。脚本不总是应该定期执行。它只需要在特定时间执行。

如果脚本必须创建任何文件或任何其他任务(例如cronjobs或其他屏幕),那将是非常有益的。这只是设计问题。

我只是有一个可怕的主意:

difference=$(($(date -d "4:00" +%s) - $(date +%s)))

if [ $difference -lt 0 ]
then
    sleep $((86400 + difference))
else
    sleep $difference
fi

您有更好的主意吗?

如果需要,将添加更多信息!


请您能澄清一下您的问题吗?当您说:“我不能离开当前正在运行的脚本”时,您是什么意思
sebelk 2013年

在重新检查之前,如何让脚本检查“唤醒”文件的存在并休眠一段时间?然后,可以利用cron来利用cron的可靠性来创建文件,但也可以使用长期存在的脚本。只是让脚本在停止睡眠时删除“唤醒”文件。
kurtm

请注意,在Mac上,您应date -d使用date -j替换4:000400
pjvandehaar,2016年

Answers:


17

terdon的建议可以奏效,但我想我的效率更高。

difference=$(($(date -d "4:00" +%s) - $(date +%s)))

if [ $difference -lt 0 ]
then
    sleep $((86400 + difference))
else
    sleep $difference
fi

这是在计算给定时间与当前时间之间的差异(以秒为单位)。如果数字为负数,我们必须加一整天的秒数(精确地为86400)以获取必须睡觉的秒数;如果数字为正数,则可以使用它。


如果系统时钟向前/向后移动会发生什么情况(例如:ntp)。
WhyNotHugo

10

假设它是一个shell脚本,那么它应该可以工作:

while [ $(date +%H:%M) != "04:00" ]; do sleep 1; done

这是24小时的时间。如果您希望在4:00 AM和4:00 PM继续执行此操作,请改用以下方法:

while [ $(date +%I:%M) != "04:00" ]; do sleep 1; done

这可能是一个选择。我只是有一个主意。我会在几分钟后回来。
BrainStone

0

OpenBSD上,可以将以下内容用于将*/55分钟的crontab(5)工作压缩为一个00小时的工作(以确保生成的电子邮件减少了,而所有电子邮件都以精确的间隔执行相同的任务):

#!/bin/sh -x
for k in $(jot 12 00 55)
  do
  echo $(date) doing stuff
  sleep $(expr $(date -j +%s $(printf %02d $(expr $k + 5))) - $(date -j +%s))
done

请注意,这date(1)也会sleep(1)在最后一次迭代时破坏设计,因为60分钟不是有效时间(除非是分钟!),因此我们无需等待任何额外时间即可获取电子邮件报告。

还要注意,如果其中一个迭代分配了5分钟以上的时间,则sleep同样会由于根本不休眠而故意失败(由于负数被解释为命令行选项,而不是绕回去)接下来的一个小时甚至是永恒的时间),从而确保您的工作仍能在分配的小时内完成(例如,如果仅一次迭代花费了超过5分钟的时间,那么我们仍然有时间赶上,而无需到下一小时的所有内容)。

printf(1)之所以需要,是因为date分钟说明需要精确的两位数。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.