这两个Cron工作有什么问题?


13

我定义了以下cron作业。

55  8   *   *   3   /usr/bin/php /home/mark/dev/processes/customClient/events.php > /home/mark/dev/processes/customClient/events-`date +%Y-%m-%d --date='last Wednesday'`-`date +%Y-%m-%d`.csv
0   9   *   *   3   /usr/bin/echo 'The csv for last week, trying my hand at automatiging this' | /usr/bin/mutt <emailaddress> -s 'Events from `date +%Y-%m-%d --date='last Wednesday'`-`date +%Y-%m-%d`' -a '/home/mark/dev/processes/customClient/events-`date +%Y-%m-%d --date='last Wednesday'`-`date +%Y-%m-%d`.csv'

如果直接从命令行运行上面的命令,它似乎可以正常工作。但是,当我今天早上检查脚本的运行时,我收到一封电子邮件,指出(我的措辞是因为我不小心删除了它们),后面的刻度线未正确关闭。


仅供参考,我刚刚重新测试了cron作业,并遇到以下错误。 /bin/sh: 1: Syntax error: EOF in backquote substitution 对于第一个cron工作。 /bin/sh: 1: Syntax error: Unterminated quoted string 对于第二个cron工作。
Mark D

2
因为如此,不推荐使用反引号。更改为$(...)可以帮助您处理报价问题...
jasonwryan 2012年

1
您肯定想检查一下我的问题。它有Stephane Chazelas的答案,解释了如何创建与cron作业将看到的环境相同的交互式shell。如果您按照他的小程序进行操作,则会得到提示,并且可以逐步测试cronjob并查看失败的地方。unix.stackexchange.com/a/56503/16841当然,这不是您所提问题的100%匹配项,但可以帮助您解决crontab问题。
jippie 2012年

Answers:


14

出于多种原因,我强烈建议您将所有重要的cron作业放入其自己的Shell脚本文件中:

  • 易于调试:您可以只运行脚本而不是复制粘贴长行,并且使用正确的shebang行,其行为比直接在crontab中具有相同命令的行为更具可预测性
  • 易于阅读:无需将它变成200字符以上的单行,可以很好地设置格式,因此每个人都易于阅读和理解
  • 将脚本添加到版本控制

8
并且将麻烦的%字符放入脚本中将防止字符cron变成换行符,这是您真正的问题。
伊恩·艾伦

我不同意。您往往会忘记哪个脚本在做什么。我说的是经验。
Sridhar Sarnobat

30

与直接按交互顺序输入交互式shell的命令相比,cron作业命令的行为有三种常见原因:

  • Cron提供了一个有限的环境,例如minimum $PATH以及其他预期变量缺失。
  • Cron /bin/sh默认情况下会调用,而您可能会以交互方式使用其他外壳程序。
  • Cron %特别对待字符(在命令中将其转换为换行符)。
  • Cron不提供终端或图形环境。

您必须在crontab文件中的所有%字符前面加上\,这告诉cron只需在命令中放入一个百分比。请记住,date在cron作业中使用命令时。

55  8   *   *   3   /usr/bin/php /home/mark/dev/processes/customClient/events.php > "/home/mark/dev/processes/customClient/events-$(date +\%Y-\%m-\%d --date='last Wednesday')-$(date +\%Y-\%m-\%d).csv"
0   9   *   *   3   /usr/bin/echo 'The csv for last week, trying my hand at automatiging this' | /usr/bin/mutt <emailaddress> -s "Events from $(date +\%Y-\%m-\%d --date='last Wednesday')-$(date +\%Y-\%m-\%d)" -a "/home/mark/dev/processes/customClient/events-$(date +\%Y-\%m-\%d --date='last Wednesday')-$(date +\%Y-\%m-\%d).csv"

我还解决了一些引用问题:

  • 除了可读性之外,这不会给您带来任何问题,但是您不应使用反引号代替命令。$(…)改为使用:它的解析规则更简单。
  • 始终在变量和命令替换处使用双引号:"$somevariable""$(somecommand)"。此处没有引号是没有害处的,因为该date命令从未针对您使用的格式返回任何特殊字符,但是您必须仔细记住哪些特殊字符,并在每次不使用引号的情况下进行检查。保持简单,除非您希望在结果上进行字段拆分和文件名生成,否则请始终使用双引号。
  • 您使用了一些单引号来防止围绕某些命令替换进行扩展。请改用双引号。

0

您似乎嵌套'mutt命令中:

“来自date +%Y-%m-%d --date='last Wednesday'- date +%Y-%m-%d的事件”

尝试使用"而不是内部,'以便该语句读取

“来自date +%Y-%m-%d --date="last Wednesday"- date +%Y-%m-%d的事件”


我不确定这就是问题所在。但是在对两个cron作业进行尝试后,执行都没有成功。
Mark D
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.