如何睡觉直到给定的日期和时间?

如何睡觉直到给定的日期和时间?

我想写一个给定日期(日-小时-分钟)的 shell,例如

10:00 AM Sun
2:30 PM Mon
...

它会休眠直到确切的日期和时间。我认为一种方法是,我可以获得当前日期并计算差异?然后将其转换为秒并在该时间内睡眠。

但是,我不太确定如何使用 shell 脚本来做到这一点?

#!/bin/bash

now=$(date '+%A %W %Y %X')
date =  2:30 PM Mon

difference = ??
sleep difference

答案1

如果允许用户使用at命令,那么这是完美的用途:

$ at 08:00 022116
at> myscript.sh
at>      <----------- ctrl-d here
job 9 at 2016-02-21 08:00

如果您收到类似“用户 blah 无法运行at”的消息,请要求 syadmin 将此用户添加到at.allow文件中或从at.deny文件中删除,具体取决于该用户在您的环境中的使用方式。

当然,除非您希望这一天的长时间睡眠发生在您的脚本中间。即使如此,您也可以将脚本分成两部分,将要保留的变量写入文件,并且当时间到来且脚本的第二部分执行时,它可以从存储的文件中读取这些变量。

答案2

#!/bin/bash
NOW=$(date +"%s")
SOON=$(date +"%s" -d "3:00 PM Sun")
INTERVAL=$(($SOON-$NOW))
sleep $INTERVAL

GNUdate允许您指定输出的格式以及要显示的日期。因此,我使用格式字符串“%s”来获取自纪元以来的时间(以秒为单位),并且对于使用参数的任意时间也是如此-d。得到差值,你就有了睡觉的时间。

检查过去的日期留给读者作为练习。

答案3

虽然您可能应该at按照已经建议的方式使用,但我有时发现以下内容在处理时间问题时很有帮助。我已经删节了一些,但链接在那里。

自纪元以来的秒数

一个近似自纪元以来经过的秒数的值。协调世界时名称(指定为s第二,几分钟,H我们的,d自每年 1 月 1 日起,日历y耳减1900)根据下面的表达式,与自纪元以来以秒表示的时间相关。

如果年份 <1970 或值为负,则关系未定义。如果年份 >=1970 并且该值非负,则根据 C 语言表达式,该值与协调世界时名称相关,其中所有变量均为整数类型:

s +  m*60 + h*3600 + d*86400          +
(y-70)*31536000    + ((y-69)/4)*86400 -
((y-1)/100)*86400  + ((y+299)/400)*86400

笔记:

表达式的最后三个术语从纪元以来的第一个闰年开始,在闰年之后的每一年添加一天。第一项从 1973 年开始每 4 年增加一天,第二项从 2001 年开始每 100 年减少一天,第三项从 2001 年开始每 400 年减少一天。公式中的除法是整数除法;也就是说,余数被丢弃,只留下整数商。

相关内容