睡眠直到下一次出现特定时间

睡眠直到下一次出现特定时间

我需要一系列命令或单个命令,该命令会休眠直到下一次出现“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

您有更好的想法吗?

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

答案1

特登的建议可行,但我想我的建议更有效。

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

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

这是计算给定时间和当前时间之间的差异(以秒为单位)。如果数字是负数,我们必须加上一整天的秒数(准确地说是 86400)才能得到我们必须睡觉的秒数,如果数字是正数,我们就可以使用它。

答案2

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

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

那是24小时的时间。如果您希望此操作在凌晨 4:00 和下午 4:00 继续,请改用以下命令:

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

答案3

开放BSD,以下内容可用于压缩*/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分钟规格预计精确为两位数。

相关内容