我有一个 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)