在 bash 中使用日期,它是否按我预期运行?

在 bash 中使用日期,它是否按我预期运行?

我有一个 bash 脚本,每周一和周四从 crontab 条目运行。

在其中,我有一个条件来运行一个或另一个代码,具体取决于下面的代码:

if [ "$(LC_TIME=C date +%a)" == "Thu" ] && [ "$(date +%d)" -ge 15 ] && 
[ "$(date +%d)" -le 21 ] && [[ "$(LC_TIME=C date +%b)" == "Feb" || "$(date +%b)" == "Apr" || "$(date +%b)" == "Jun" || "$(date +%b)" == "Aug" || "$(date +%b)" == "Oct" || "$(date +%b)" == "Dec" ]]
then

    // condition a

else

    // condition b

fi

我不确定如何最好地测试上述内容,并且对 bash 不太有信心,我希望“条件 a”将在二月、四月等的每个第三个星期四运行,否则“条件 b”将运行。

提前致谢。

答案1

您只需致电date一次。我会这样写:

# ask date for the weekday, date and month: store into variables
read -r day date month < <( LC_TIME=C date "+%a %_d %b" )

# the 3rd Thu of the month has date between 15 and 21 inclusive
if  [[ $day == "Thu" ]] &&
    (( 15 <= date && date <= 21 )) &&            
    [[ ":Feb:Apr:Jun:Aug:Oct:Dec:" == *:"$month":* ]]
then
    echo "code a"
else
    echo "code b"
fi

这依赖于 bash==操作符是模式匹配,不是字符串相等运算符。

答案2

看起来大约是的,您已将 放置||在 中,因此和[[ .. ]]之间不应该发生冲突。&&||

不管怎样,你可以稍微简化一下。无需date为每个测试单独运行,只需先将值保存到变量中,weekday=$(LC_TIME=C date +%a)等等。

此外,月份列表看起来包含偶数月份(2、4、6、8、10 和 12),因此您可以测试一下:([ "$((month % 2))" = 0 ]%模运算符)。

或者完整的,如果我没有犯任何错误的话:

weekday=$(LC_TIME=C date +%a)
dom=$(date +%-d)
month=$(date +%-m)

if [ "$weekday" = "Thu" ] && 
   [ "$dom" -ge 15 ] &&  [ "$dom" -le 21 ] && 
   [ "$((month % 2))" = 0 ]; then
        echo A
else
        echo B
fi

使用%-m( 和%-d) 有date 不是打印前导零。 Bash 会将其解释为数字是八进制的。另一种方法是使用 删除它month=${month#0}

date -d您可以通过在作业中使用来测试任意日期:

date=2019-04-17
weekday=$(LC_TIME=C date -d "$date" +%a)
dom=$(date -d "$date" +%-d)
month=$(date -d "$date" +%-m)

相关内容