如果当前时间在 23:00 和 06:30 之间,我无法掌握如何从 bash 脚本中正确检查。我正在尝试运行无限循环来检查现在的时间,并在时间范围介于晚上 11 点到早上 6:30 之间时执行某些操作。这是我到目前为止写的内容,第二天就不起作用了:
fireup()
{
local starttime=$(date --date="23:00" +"%s")
local endtime=$(date --date="06:30" +"%s")
while :; do
local currenttime=$(date +%s)
if [ "$currenttime" -ge "$starttime" -a "$currenttime" -ge "$endtime" ]; then
do_something
else
do_something_else
fi
test "$?" -gt 128 && break
local currenttime=$(date +%s)
done &
}
我做错了什么?
答案1
如果您需要的只是检查是否HH:MM
在 23:00 和 06:30 之间,那么不要使用 Unix 时间戳。只需直接检查HH:MM
值:
fireup()
{
while :; do
currenttime=$(date +%H:%M)
if [[ "$currenttime" > "23:00" ]] || [[ "$currenttime" < "06:30" ]]; then
do_something
else
do_something_else
fi
test "$?" -gt 128 && break
done &
}
笔记:
- 时间 in
HH:MM
将按字典顺序排列,因此您可以直接将它们作为字符串进行比较。 - 避免使用
-a
或-o
在[ ]
,使用||
和&&
代替。 - 因为这是 bash,所以
[[ ]]
更喜欢[ ]
,它让生活更轻松。
答案2
如果您想更明确地说明要匹配的时间,可以使用语句case
。这是一个 24 小时循环,其中包含一个 case 语句,指示当前时间是否与您的范围匹配:
for hh in {00..23}
do
for mm in {00..59}
do
case $hh:$mm in
(23:*) echo YES $hh:$mm;;
(0[012345]:*) echo YES $hh:$mm;;
(06:[012]*) echo YES $hh:$mm;;
(*) echo NO $hh:$mm;;
esac
done
done
要在脚本中使用它,只需将变量替换为调用date
:
case $(date +%H:%M) in
(23:*) echo YES;;
(0[012345]:*) echo YES;;
(06:[012]*) echo YES;;
(*) echo NO;;
esac
您可能会考虑对 CPU 更友好,并计算(现在)和下一个开始时间之间的时间量,并且sleep
在那段时间里。
答案3
您可以将时间转换为自“今天”开始以来的秒数,然后检查秒值是否大于23*60*60
(82800) 或小于6*60*60+30*60
(23400)。
要获取自“今天”开始以来的秒数,您可以执行以下操作:
secsSinceMidnight=$(( $(date +%s) - $(date -d '00:00:00' +%s) ))
测试将是:
[[ $secsSinceMidnight -lt 23400 || $secsSinceMidnight -gt 82800 ]] && echo YES
答案4
我也有类似的情况。我的目标是提供一个对于非 UNIX 极客来说非常容易维护的解决方案。
当我的 Linux 服务器重新启动时,它会运行一个发送警报的脚本。但是,如果这种情况发生在我们的“维护窗口”(定义为周六晚上 11 点到周日早上 6 点之间)的一部分,我不想发送该页面,因为在此窗口期间重新启动是可以的(应用补丁等)。我已经测试过它,它确实按预期工作(据我所知)。
以下是日历供参考:
June 2018
Su Mo Tu We Th Fr Sa
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
这是我的测试代码:
FMT='+%k:%a' # i.e. Sat:23 for Saturday at 11pm local time
TESTDATE1=$(date -d '2018-06-23 14:30:00' $FMT)
TESTDATE2=$(date -d '2018-06-23 23:59:59' $FMT)
TESTDATE3=$(date -d '2018-06-24 00:00:00' $FMT)
TESTDATE4=$(date -d '2018-06-24 05:59:59' $FMT)
TESTDATE5=$(date -d '2018-06-24 08:01:00' $FMT)
for VAL in "${TESTDATE1}" $TESTDATE2 $TESTDATE3 $TESTDATE4 $TESTDATE5
do
#extract the 24 hour value and the day
HH="$(echo ${VAL} | cut -d':' -f1)"
DAY="$(echo ${VAL} | cut -d':' -f2)"
echo Testing $VAL $HH $DAY
if [[ "$DAY" = "Sat" && $HH -ge 23 ]]; then
echo ' Shhhh People are trying to sleep ... Sat window'
elif [[ "$DAY" = "Sun" && $HH -le 6 ]]; then
echo ' People are trying to sleep ... Sun window'
else
echo ' PAGE SOMEONE - time is outside the Maintenance Window'
fi
done
这是输出
Testing 14:Sat 14 Sat
PAGE SOMEONE - time is outside the Maintenance Window
Testing 23:Sat 23 Sat
Shhhh People are trying to sleep ... Sat window
Testing 0:Sun 0 Sun
People are trying to sleep ... Sun window
Testing 5:Sun 5 Sun
People are trying to sleep ... Sun window
Testing 8:Sun 8 Sun
PAGE SOMEONE - time is outside the Maintenance Window