这两个 cron 作业有什么问题?

Mar*_*k D 14 command-line cron

我定义了以下 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'
Run Code Online (Sandbox Code Playgroud)

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

Gil*_*il' 33

与直接键入交互式 shell 的命令相比,cron 作业命令的行为不同的常见原因有以下三个,按共性的粗略顺序排列:

  • Cron 提供了一个有限的环境,例如,一个 minimum$PATH和其他预期变量缺失。
  • /bin/sh默认情况下,Cron 会调用,而您可能会以交互方式使用其他一些 shell。
  • Cron 对%字符进行了特殊处理(它在命令中变成了换行符)。
  • Cron doesn't provide a terminal or graphical environment.

You must precede all % characters with a \ in a crontab file, which tells cron to just put a percent in the command. Remember that when you use the date command in a cron job.

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"
Run Code Online (Sandbox Code Playgroud)

I also fixed some quoting problems:

  • This wasn't causing you problems other than with legibility, but you shouldn't use backticks for command substitution. Use $(…) instead: its parsing rules are simpler.
  • 始终在变量和命令替换周围使用双引号:"$somevariable", "$(somecommand)". 此处缺少引号是无害的,因为该date命令从未为您使用的格式返回任何特殊字符,但您必须仔细记住哪些字符是特殊字符,并在每次不加引号的替换时进行检查。保持简单,除非您希望对结果进行字段拆分和文件名生成,否则始终使用双引号。
  • 您有一些单引号阻止围绕某些命令替换进行扩展。请改用双引号。


jan*_*nos 16

我强烈建议将任何非平凡的 cron 作业放入他们自己的 shell 脚本文件中,原因有很多:

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

  • 将麻烦的 `%` 字符放在脚本中会阻止 `cron` 将它们转换为换行符,这才是你真正的问题。 (8认同)