fangpsh's blog

cronic脚本修正

实习期间做的一个东西需要读写控制crontab 的任务,失败需要报警。crontab本身有报警,但是非常不友好,例如cron job如果有任何输出(标准输出或者标准错误输出),都会发送邮件通知,并且还需要在每台机器上配置smtp,非常麻烦。所以想着就在前面直接套了个脚本,如果任务异常,用curl调一下远程服务的api发送邮件即可。

找到这样一份shell脚本-- Cronic,不过这份脚本不满足一些需求,并在部署测试的时候遇到一些bug,修正如下。

上文脚本链接中的例子是:

0 1 * * * cronic backup

backup指的是一条命令,不能使用组合的命令,不然会出现意想不到的事情。例如:

30 23 * * * cronic cd /named/zone_bak  && find ./ -maxdepth 1 -mtime +2 | xargs -i rm -rf {}

如果用root 用户执行这个任务,将直接导致 /root下两天前的所有文件被删。。至于为什么,看原来脚本的写法就知道了:

"$@" >$OUT 2>$TRACE

解决方法是把cron job都写成一个脚本,然后 cronic command 来调用,但是开发同学肯定不爽,SA也不爽。
那就加单引号吧,bash脚本中加了单引号的所有特殊字符不会被展开,当然command里面的单引号得用转义:

cronic 'command'

原来脚本中执行命令的部分使用eval改写,顺带解决下重定向输出的bug(想想如果command中已经包含了重定向的操作,会发生什么奇怪的事情,2333):


eval "("$@")" >$OUT 2>$TRACE

完整脚本见 cronic.sh

另外有一个Python版本的,见 pycronic: 使crontab的报警更无痛