我必须将 cronjob 设置为每个月的第一个工作日,这意味着脚本应该在每个月的第一个工作日运行。
如果假设第一个工作日是假期,那么脚本应该在第二个工作日运行。 例如:2015 年 1 月 1 日是假期,那么脚本应该在 2015 年 1 月 2 日运行。
最佳答案
首先,运行date
命令:
$ date '+%x'
12/29/2014
%x
告诉 date 以当前语言环境的格式显示今天的日期。使用完全相同的格式,将假期列表放入名为holidays
的文件中。例如:
$ cat holidays
01/01/2015
07/04/2015
接下来,创建以下 shell 脚本:
#!/bin/sh
dom=$(date '+%d') # 01-31, day of month
year=$(date '+%Y') # four-digit year
month=$(date '+%m') # two-digit month
nworkdays=0
for d in $(seq 1 $dom)
do
today=$(date -d "$year-$month-$d" '+%x') # locale's date representation (e.g. 12/31/99)
dow=$(date -d "$year-$month-$d" '+%u') # day of week: 1-7 with 1=Monday, 7=Sunday
if [ "$dow" -le 5 ] && grep -vq "$today" /path/holidays
then
workday=Yes
nworkdays=$((nworkdays+1))
else
workday=
fi
done
[ "$workday" ] && [ "$nworkdays" -eq 1 ] && /path/command
其中 /path/command
替换为您想在每月第一个工作日运行的任何命令。此外,将 /path/holidays
替换为您的 holidays
文件的正确路径。
最后,告诉 cron 每天运行上面的脚本。您的命令
将仅在该月的第一个工作日执行。
工作原理
让我们看一下脚本的核心:
for d in $(seq 1 $dom);做
这会启动一个循环,运行变量
d
,从 1 到当前的日期。today=$(date -d "$year-$month-$d"'+%x') # 语言环境的日期表示(例如 12/31/99)
这会将
today
设置为本月和本年的d
日的日期字符串。dow=$(date -d "$year-$month-$d"'+%u') # 星期几:1-7 其中 1=星期一,7=星期日
这会将
dow
设置为d
的星期几,1=星期一,7=星期日。if [ "$dow"-le 5 ] && grep -vq "$today"/path/holidays
测试
"$dow"-le 5 ]
验证d
是工作日(周一至周五)。测试grep -vq "$today"/path/holidays
验证d
的日期没有出现在holidays
文件中。如果两个测试都为真,那么第d
天是工作日并且执行then
子句:然后工作日=是; nworkdays=$((nworkdays+1))
then
子句将workday
设置为Yes
并增加本月到目前为止的工作日计数:nworkdays
else workday=
else
子句将workday
设置回空字符串。fi
fi
表示if
语句结束。完成
done
表示for
循环结束。[ "$workday"] && [ "$nworkdays"-eq 1 ] &&/path/command
for
语句中的最后一个循环是针对今天的日期。因此,如果在循环结束后workday=Yes
,那么今天是工作日。此外,如果nworkdays=1
,则今天是该月的第一个 工作日。如果两个条件都为真,则执行您的命令/path/command
。
关于bash - 如何在 cron 中的每个月的第一个工作日运行脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27700043/