如果 2 天后是该月的第一天... 则是倒数第二个工作日。但是,周六和周日呢?

如果 2 天后是该月的第一天... 则是倒数第二个工作日。但是,周六和周日呢?

我需要你的帮助来构建一个 cron 作业,在每个月倒数第二个工作日运行。我可以按照下面所示执行 LW,但我不确定如何执行倒数第二个。我需要你的帮助和建议。

@MWE 好心地为我提供了一个可能的解决方案,但它似乎并不适用于所有测试场景。

code:
#!/bin/bash
date
WEEKDAY=$(date +%u)
# If detect the montday in 2 days.
if [ $(date +%d -d "2 day") -eq 1 ] && [ ${WEEKDAY} -lt 5 ] ; then
   echo "This is the 2. last working day of the month"
# If detect the montday in 5 days.
elif [ $(date +%d -d "5 day") -eq 1 ] && [ ${WEEKDAY} -eq 5 ] ; then
   echo "This is the 2. last working day of the month"
else
  exit
fi

测试场景:我已将服务器上的系统日期修改为 2019 年 8 月 29 日(**这是系统上的倒数第二个工作日期)

调试模式下的脚本退出:

[oracle@rdbauroral01v ~]$ bash -x ./crontest.sh
+ date
Thu Aug 29 13:28:20 UTC 2019
++ date +%u
+ WEEKDAY=4
++ date +%d -d '2 day'
+ '[' 31 -eq 1 ']'
++ date +%d -d '5 day'
+ '[' 03 -eq 1 ']'
+ exit

感谢您的帮助。

答案1

就像在脚本中而不是在 crontab 中解决该问题的简单想法一样:

当明天 = 一个月的 1 时,一个月的最后一天永远是这一天。

这意味着:让我们从纪元秒数中取出当前日期,并添加 24 小时。然后让我们取出它是月份中的哪一天:

TIMESTAMP=$(date +%s)
TIMESTAMP_TOMORROW=$(( $TIMESTAMP + 86400 ))

计算明天的月份日期:

DAYOFMONTH=$(date --date="@${TIMESTAMP_TOMORROW}" +%e)

如果 DAYOFMONTH == 1,则今天是该月的最后一天。然后执行您想要的操作。如果不是 == 1,则退出。

您可以在这里找到替代方案:https://stackoverflow.com/questions/6139189/cron-job-to-run-on-the-last-day-of-the-month

TODAY=`date +%d`
TOMORROW=`date +%d -d "1 day"`

# See if tomorrow's day is less than today's
if [ $TOMORROW -lt $TODAY ]; then
echo "This is the last day of the month"
# Do stuff...
fi

或者:

0 23 28-31 * * [ `/bin/date -d +1day +\%d` -eq 1 ] && myscript.sh

最后但并非最不重要的一点。将 $(( $TIMESTAMP + 86400 * 2 )) 乘以 2,得到倒数第二天。

或者:

TOMORROW=$(date +%d -d "2 day")

或者:

[ $(/bin/date -d +2day +\%d) -eq 1 ]

答案2

2. 取出每月的最后一个工作日。%u 从星期一开始作为第一天。%w 从星期日开始。

  1. 最后一个工作日通常是星期四。所以是第四个工作日。我们现在必须考虑未来 6 天。-> 意思是,本月的最后一个工作日必须在本月第五天之前。
WEEKDAY=$(date +%u)
TOMORROW=$(date +%d -d "5 day")
if [ ${WEEKDAY} -eq 4 ] && [ $TOMORROW -lt 5 ]; then
echo "This is the 2. last working day of the month"
fi

答案3

在 crontab 中,您可以将执行限制在工作日和月日。两者结合是一个好的开始。因此,您可以确保脚本仅在工作日运行。在月日感知的二月(28 天等)或仅 30 天。它不会在每个月的 31 日结束!因此,为了安全起见,也许可以使用 20-31 天。

     field          allowed values
          -----          --------------
          minute         0-59
          hour           0-23
          day of month   1-31
          month          1-12 (or names, see below)
          day of week    0-7 (0 or 7 is Sunday, or use names)

Crontabentry 喜欢:

0 0 20-31 * 1-5 ./scriptname

这部分很容易找出,第二个、第三个或第四个是星期几。为什么?脚本仅在工作日由 crontab 运行。所以我们不必关心星期六或星期日。另一种方法是,我们可以检查星期几 $(date +%u) 是否在 1-5 之间。这是工作日。

代码现在很简单:

如果 2 天后是该月的第一天... 则是倒数第二个工作日。但是,周六和周日呢?

你现在需要一个案例。从星期一到星期四总是一个工作日。所以规则是,如果它在 2 天后的第一个月日,它就是第二个工作日。只有星期五必须是 5 天后的月初才能成为第二个工作日。或者一个月的第一天必须是星期二。

WEEKDAY=$(date +%e)
# 1. If detect the montday in 2 days.
if [ $(date +%d -d "2 day") -eq 1 ] && [ ${WEEKDAY} -lt 5 ] ; then
   echo "This is the 2. last working day of the month"
# 1. If detect the montday in 5 days.
elif [ $(date +%d -d "5 day") -eq 1 ] && [ ${WEEKDAY} -eq 5 ]
   echo "This is the 2. last working day of the month"
else 
  exit
fi

希望我没有错过任何东西。

答案4

请尝试以下文章来更好地理解 cron 中允许的表达式类型,

具体来说,如果您在“月份中的某天”指定为“28W” --> 它会在 28 日执行,或者如果 28 日是星期六/星期日,它会在最近的工作日执行(如果 28 日是星期六,那么它会在 27 日执行;如果 28 日是星期日,那么它会在 29 日执行)

參考文獻:http://www.brightxpress.com/user/appendix/cron_expressions.htm

相关内容