抽象
正确的代码应为:
#!/bin/sh
[ "$#" -eq 0 ] && echo "Usage: $0 command [args]" && exit 1
[ "$(date -d tomorrow +'%d')" = 01 ] || exit 0
exec "$@"
调用此脚本end_of_month.sh
,在cron中的调用很简单:
00 12 28-31 * * /path/to/script/end_of_month.sh command
这将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。从书中粘贴代码(在星号之后),它将向您显示上面列出的错误以及“缺少提示”。Shellcheck中没有任何错误的脚本是这样的:
#!/bin/sh
if [ "$(date +%d -d tomorrow)" = 01 ] ; then script.sh; fi
该站点之所以有效,是因为所写的是“外壳代码”。那是在许多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 "$@"
调用此脚本end_of_month.sh
,在cron中的调用很简单:
00 12 28-31 * * /path/to/script/end_of_month.sh command
这将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....