bash - 如何在 cron 中的每个月的第一个工作日运行脚本?

标签 bash unix cron

我必须将 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/

相关文章:

Cron 表达式 (Quartz) 用于每午夜 12 点运行的程序

bash - 如何使一个简单的 if 语句太长?

java - ssh后在bash脚本中运行两个java程序

bash - 带有 bash 变量的 JMESPath 查询表达式

java - 为什么 Log4j2 在 Windows bash 控制台中抛出错误

bash - 在 unix 中按数字和字典对单个字段进行排序?

linux - Unix - ls 命令将一些 "outputted"文本显示为文件

c - unix 进程 ID 的基数是 10 吗?

linux - 如何设置cron来显示gui应用程序

ruby-on-rails-4 - 在美国午夜在 rails 中安排 `whenever` 任务的最佳方法是什么?