我想写一个给定日期(日-小时-分钟)的 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 年减少一天。公式中的除法是整数除法;也就是说,余数被丢弃,只留下整数商。