shell Bash-Script:如何测试小时数是否为偶数?

41ik7eoe  于 2023-04-21  发布在  Shell
关注(0)|答案(5)|浏览(223)

在一个bash脚本(每30分钟运行一次)中,我想每隔一个偶数小时(和0分钟)执行一次操作,所以我想测试小时数是否是偶数。所以我使用这个:

HEURE=$(date +"%H")
        MINUTES=$(date +"%M")
        HEURE_PAIRE=""
        MINUTES_ZERO=""
        [[ $((HEURE % 2)) -eq 0 ]] && HEURE_PAIRE="OUI" || HEURE_PAIRE="NON"
        [[ $MINUTES -eq 0 ]] && MINUTES_ZERO="OUI" || MINUTES_ZERO="NON"
        if [[ "${HEURE_PAIRE}" == "OUI" ]] && [[ "MINUTES_ZERO" == "OUI" ]]; then
            # My code
        fi

但是我得到了一个错误,这一行(在我的脚本中是n°170)[[ $((HEURE % 2)) -eq 0 ]] && HEURE_PAIRE="OUI" || HEURE_PAIRE="NON",当它是08:0008:3009:0009:30时,但不是10:0010:30。请看我得到的错误:

/volume4/docker/_Scripts-DOCKER/driver-pkgctl-r8152-restart-reload.sh: line 170: 08: value too great for base (error token is "07")
/volume4/docker/_Scripts-DOCKER/driver-pkgctl-r8152-restart-reload.sh: line 170: 09: value too great for base (error token is "09")

我希望它能像这样工作:对于08:0008%2应该返回0作为结果,证明小时是偶数。对于09:0009%2应该返回1作为结果,证明小时不是偶数。没有错误
我假设是89之前的0 ...但我不知道如何解决这个问题。
我找到了一个解决方法with this question,添加了以下内容:

HEURE=${HEURE#0}

似乎起作用了。
我的问题是:有没有更好的方法来实现我的愿望?
先谢谢你了。

epfja78i

epfja78i1#

修改脚本:

强制底座10¹:

#!/bin/bash

heure=10#$(date +"%H") minutes=10#$(date +"%M")
if (( heure % 2 == 0 && minutes == 0 )); then
    # My code
fi

使用POSIX * 参数展开 * 的另一种方法

#!/bin/bash

heure=$(date +"%H") minutes=$(date +"%M")
if (( ${heure#0} % 2 == 0 && ${minutes#0} == 0 )); then
    # My code
fi

使用crontab的其他方法

*/30 * * * * /path/to/script

Don't use UPPER case variables
((...))$((...))是算术命令,如果表达式非零,则返回退出状态0,如果表达式为零,则返回退出状态1。如果需要副作用(赋值),则也用作“let”的同义词。请参见http://mywiki.wooledge.org/ArithmeticExpression
¹在bash的算术运算中,如果有一个像08这样的前导0,它被视为八进制数。为了强制使用base10,我在小时和分钟上使用10#前缀
无需在[[ ... ]]语法中加上引号,请参见http://mywiki.wooledge.org/BashFAQ/031http://mywiki.wooledge.org/BashGuide/TestsAndConditionals

5f0d552i

5f0d552i2#

设置基础是bash的一个好方法。
对于不支持此功能的POSIX shell,还有其他选择。

非零前缀:

heure=$(date +1%H)
...

去掉前导零:

heure=$(date +%H)
heure=${heure#0}
...

文字对比:

heure=$(date +%H)
...
case $heure in ?[02468]) ... ;; esac
...
e1xvtsh3

e1xvtsh33#

首先,这是不好的:

HEURE=$(date +"%H")
MINUTES=$(date +"%M")

时间可以切换,例如从10:59到11:00之间。然后你得到了错误的10:00。
使用任一

time=$( date +%H:%M )
HEURE="${time%:*}"
MINUTES="${time#*:}"

或者...

time=$( date +%s )
HEURE=$( date -d@$time +%H )
MINUTES=$( date -d@$time +%M )

在这两个例子中,你只能得到一次时间。在第二个例子中,你将得到纪元时间,然后从这个时间计算每分钟的小时。第一个例子似乎更有效。
然后将[[ $((HEURE % 2)) -eq 0 ]]替换为(( !( 10#$HEURE % 2 )))(( ( 10#$HEURE % 2 ) == 0 ))。前缀10#强制计算为十进制数。
最后一点:一般来说,局部变量名使用小写字母或混合大小写。

v7pvogib

v7pvogib4#

不使用算术表达式的替代方法:

#!/bin/bash

hm=$(date +%H%M)
if [[ $hm = ?[02468]00 ]]; then
    # do stuff
fi

或者,在POSIX shell中:

#!/bin/sh

hm=$(date +%H%M)
case $hm in
    ?[02468]00) do_stuff ;;
esac

或者,在单个操作中使用Bash算法:

#!/bin/bash

if (( 10#$(date +%H%M) % 200 == 0 )); then
        echo "It is time" 
fi
jutyujz0

jutyujz05#

在数字上下文中,以零开头的字符串被认为是八进制的。因此,08是错误的。
不过,我不会用人工的方法来测试你的情况。相反,我会做一些像

if [[ $(date +%HM) == ?[02468]00 ]]
then
  ....
fi

相关问题