我正在Fedora 27机器上编写bash脚本。该脚本会定期运行Python程序,偶尔显示进度消息。除了在行中添加时间间隔并将其添加到存储在变量中的时间之外,该行均有效。
有人知道如何做到这一点吗?
这是脚本的最低版本。
#!/usr/bin/env bash
next_run_dat=${1}
echo -n 'Next run will be at: ';echo ${next_run_dat}
now_dat=`date +'%Y-%m-%d %H:%M:%S'`
echo -n 'The time is now: ';echo ${now_dat}
while [[ ${now_dat} < ${next_run_dat} ]]
do
sleep 10
now_dat=`date +'%Y-%m-%d %H:%M:%S'`
echo -n 'The time is now: ';echo ${now_dat}
done
while true
do
echo 'This line represents a run.'
sleep 5
# ==> PROBLEM LINE BELOW <==
next_run_dat=$(date -d "${next_run_dat} + 25 seconds" +'Y-%m-%d %H:%M:%S')
echo -n 'Next run will be at: ';echo ${next_run_dat}
now_dat=`date +'%Y-%m-%d %H:%M:%S'`
echo -n 'The time is now: ';echo ${now_dat}
while [[ ${now_dat} < ${next_run_dat} ]]
do
sleep 5
now_dat=`date +'%Y-%m-%d %H:%M:%S'`
echo -n 'The time is now: ';echo ${now_dat}
done
done
这是运行最低版本的输出:
$ bash control_bash_minimal.sh '2018-07-23 09:38:00'
Next run will be at: 2018-07-23 09:38:00
The time is now: 2018-07-23 09:37:36
The time is now: 2018-07-23 09:37:46
The time is now: 2018-07-23 09:37:56
The time is now: 2018-07-23 09:38:06
This line represents a run.
date: invalid date ‘2018-07-23 09:38:00 + 25 seconds’
Next run will be at:
The time is now: 2018-07-23 09:38:11
This line represents a run.
Next run will be at: Y-07-23 09:38:41
The time is now: 2018-07-23 09:38:16
^C
非常感谢您对此问题的帮助。
答案 0 :(得分:3)
输入格式将+
用于两个不同的目的:在时间戳中指定时区,并指定相对于时间戳的相对增量。在您的情况下,date
尝试将25 seconds
解析为时区。如果您指定了明确的时区,则可以添加偏移量:
$ date -d "2018-07-23 09:38:00"
Mon Jul 23 09:38:00 EDT 2018
$ date -d "2018-07-23 09:38:00 + 25 seconds"
date: invalid date ‘2018-07-23 09:38:00 + 25 seconds’
# I used a minus sign here to make the output match
# the first example...
$ date -d "2018-07-23 09:38:00-0400 + 25 seconds"
Mon Jul 23 09:38:25 EDT 2018
# ... but positive timezone offsets work too
# (Note that date uses the timezone to parse the
# input, but converts the result to your local
# timezone.)
$ date -d "2018-07-23 09:38:00+0100 + 25 seconds"
Mon Jul 23 04:38:25 EDT 2018
也许可以在不添加我不知道的明确时区的情况下进行歧义消除。
答案 1 :(得分:2)
注释:这是对chepner's answer
的扩展注释摘自GNU coreutils的手册:
组合的日期和时间项 ISO 8601日期和时间扩展格式由ISO 8601日期,“ T”字符分隔符和ISO 8601时间组成。如果将“ T”替换为空格,则也可以识别这种格式。
在这种格式下,一天中的时间应使用24小时表示法。允许小数秒,小数点前可以带逗号或句点。不支持ISO 8601的分钟和小时分数。通常,主机支持纳秒级的时间戳分辨率;多余的精度会被静默丢弃。
可悲的是,他们没有提及是否应包括时区。
尝试解开source code和用过的GNUlib给我一种chepner是正确的感觉。符号的双重用法使日期解析器失效。更准确地说,它假设+
或-
之后的第一个数字是时区偏移量,以小时为单位。通常,时区的格式为+HH:MM
或-HH:MM
,但是单个数字将其实现为+HH:00
。显然,该数字必须小于或等于24。例如:
$ TZ=UTC date -d "2018-07-23T09:38:00 + 9 seconds"
Mon 23 Jul 00:38:01 UTC 2018
$ TZ=UTC date -d "2018-07-23T09:38:00 + 9 2 seconds"
Mon 23 Jul 00:38:02 UTC 2018
此处,假定日期为UTC + 09:00,然后转换为UTC,并以一秒为单位递增,在第二种情况下为2秒。
OP的示例失败,因为假设+ 25 seconds
为UTC + 25:00,但这是无效的时区:
$ date -d "2018-07-23T09:38:00 + 25 seconds"
date: invalid date ‘2018-07-23T09:38:00 + 25 seconds’
那么,如何增加相对时间而不落入TZ陷阱?
日期解析器期望相对时间使用带符号或无符号的数字。因此,我们实际上并不需要添加加号,因此可以通过删除+
符号来利用它来增加时间:
$ date -d "2018-07-23T09:38:00 25 seconds"
Mon 23 Jul 09:38:25 UTC 2018
这仅在您添加相对时间时有效,而在您减去时不起作用。但同样,我们可以通过在解析器中添加前零秒,几小时或几天或任何零天来欺骗解析器:
$ date -d "2018-07-23T09:38:00 - 25 seconds"
date: invalid date ‘2018-07-23T09:38:00 - 25 seconds’
$ date -d "2018-07-23T09:38:00 0 hours - 25 seconds"
Mon 23 Jul 09:37:35 UTC 2018
您还可以使用关键字next
和prev
:
$ date -d "2018-07-23T09:38:00 next 25 seconds"
Mon 23 Jul 09:38:25 UTC 2018
$ date -d "2018-07-23T09:38:00 prev 25 seconds"
Mon 23 Jul 09:37:35 UTC 2018
如果时区不是很重要,只需在UTC中运行,只需在字符串末尾添加Z
。
$ date -d "2018-07-23T09:38:00Z + 25 seconds"
Mon 23 Jul 09:38:25 UTC 2018
但是最简单的方法是使用浮点数。由于时区的时区为HH:MM,浮点数不能解释为时区,因此
$ date -d "2018-07-23T09:38:00 + 25.0 seconds"
Mon 23 Jul 09:38:25 UTC 2018
$ date -d "2018-07-23T09:38:00 - 25.0 seconds"
Mon 23 Jul 09:37:35 UTC 2018
答案 2 :(得分:1)
您可以使用BASH算术将日期转换为EPOCH秒,并且不添加秒数:
dt='2018-07-23 09:38:00'
newdt=$(date -d "@$(( $(date -d "$dt" +%s) + 25))" +'%Y-%m-%d %H:%M:%S')
echo "$newdt"
2018-07-23 09:38:25