Abs*_*cDo 10 cron shell-script date test
我从指令中阅读了在本月最后一天安排脚本的说明:
注意:
精明的读者可能想知道如何设置命令在每个月的最后一天执行,因为您无法将 dayofmonth 值设置为涵盖每个月。这个问题一直困扰着 Linux 和 Unix 程序员,并产生了很多不同的解决方案。一种常用的方法是添加一个 if-then 语句,该语句使用 date 命令来检查明天的日期是否为 01:Run Code Online (Sandbox Code Playgroud)00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1
这会在每天中午 12 点检查是否是该月的最后一天,如果是,则 cron 运行该命令。
如何[`date +%d -d tomorrow` = 01 ]
工作?
陈述正确then; command1
吗?
ImH*_*ere 17
正确的代码应该是:
#!/bin/sh
[ "$#" -eq 0 ] && echo "Usage: $0 command [args]" && exit 1
[ "$(date -d tomorrow +'%d')" = 01 ] || exit 0
exec "$@"
Run Code Online (Sandbox Code Playgroud)
调用这个脚本end_of_month.sh
,cron 中的调用很简单:
00 12 28-31 * * /path/to/script/end_of_month.sh command
Run Code Online (Sandbox Code Playgroud)
这将end_of_month
仅在第 28、29、30 和 31 天运行脚本(内部将检查该天是否为当月的最后一天)。无需在任何其他日期检查月末。
这是 Richard Blum 所著的“Linux Command Line and Shell Scripting Bible”一书中的引述,Christine Bresnahan pp 442,第三版,John Wiley & Sons ©2015。
是的,这就是它所说的,但这是错误的/不完整的:
fi
。[
和以下之间需要空格`
。`…`
。"$(…)"
;
后面还有一个then
我怎么知道?(好吧,根据经验?)但您可以尝试Shellcheck。粘贴书中的代码(在星号之后),它会显示上面列出的错误以及“丢失的shebang”。Shellcheck 中没有任何错误的脚本是这样的:
#!/bin/sh
if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi
该站点有效,因为编写的是“shell 代码”。这是一种适用于许多 shell 的语法。
shellcheck 没有提到的一些问题是:
假设 date 命令是 GNU 日期版本。带有一个-d
接受tomorrow
值的选项(busybox 有一个 -d 选项但明天不理解,BSD 有一个-d
选项但与“显示”时间无关)。
最好在所有选项之后设置格式date -d tomorrow +'%d'
。
cron 开始时间始终是本地时间,如果设置或取消设置 DST(夏令时),这可能会使一项作业比确切的日期早 1 小时开始。
我们完成的是一个可以用 cron 调用的 shell 脚本。我们可以进一步修改脚本以接受要执行的程序或命令的参数,如下所示(最终是正确的代码):
#!/bin/sh
[ "$#" -eq 0 ] && echo "Usage: $0 command [args]" && exit 1
[ "$(date -d tomorrow +'%d')" = 01 ] || exit 0
exec "$@"
Run Code Online (Sandbox Code Playgroud)
调用这个脚本end_of_month.sh
,cron 中的调用很简单:
00 12 28-31 * * /path/to/script/end_of_month.sh command
Run Code Online (Sandbox Code Playgroud)
这将end_of_month
仅在第 28、29、30 和 31 天运行脚本(内部将检查该天是否为当月的最后一天)。无需在任何其他日期检查月末。
确保包含正确的路径。cron 中的 PATH 不会(不太可能)与用户 PATH 相同。
请注意,有一个已测试的月末脚本(如下所示)可以调用许多其他实用程序或脚本。
这也将避免 cron 使用完整命令行生成的额外问题:
%
即使用'
或引用"
(\
此处仅适用),Cron也会在任何命令行上拆分命令行。这是 cron 作业失败的常见方式。您可以end_of_month.sh
通过使用 faketime 进行测试来测试脚本在某个日期是否正常工作(无需等到月底才发现它不起作用):
$ faketime 2018/10/31 ./end_of_month echo "Command will be executed...."
Command will be executed....
Run Code Online (Sandbox Code Playgroud)
假设语法错误是固定的,并且命令稍微重新编写以减少冗长:
00 12 28-31 * * [ "$( date -d tomorrow +\%d )" != "01" ] || command1
Run Code Online (Sandbox Code Playgroud)
这运行date +%d -d tomorrow
(假设使用的是 GNU date
)以获取明天的日期作为两位数。如果数字不是01
,则今天不是该月的最后一天。在这种情况下,试验成功,command1
则不会执行。作业在可能是本月最后一天的中午运行。
原始命令:
00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command1
Run Code Online (Sandbox Code Playgroud)
这有几个问题:
[
。;
直接之后then
。%
在 cron 作业规范中是特殊的,必须将其转义为\%
(参见man 5 crontab
)。fi
与if
. 归档时间: |
|
查看次数: |
5787 次 |
最近记录: |