首页 > 解决方案 > 使用 printf 打印出在 Crontab 中运行程序之前的时间,给出“无效指令”错误

问题描述

我正在运行 Ubuntu 21.10 并尝试设置 crontab 任务。

我希望在任务开始之前将日期和时间打印到控制台,所有这些都记录到日志文件中。

这就是我目前所拥有的。

{ printf "\%(\%Y-\%m-\%d \%H:\%M:\%S)T  Started Task\n"; <run task> } >> /path/to/log/file

当我输入时,printf "%(%Y-%m-%d %H:%M:%S)T Started Task\n"我得到了预期的输出:

2021-10-20 15:22:03 Started Task

但是,在 crontab 中,我知道您必须逃避"%"with \。除非即使在逃脱了所有之后,%我最终还是会出现错误:

/bin/sh: 1: printf: %(: invalid directive

无论如何尝试格式化 crontab,我仍然会遇到同样的错误。

如果有人知道我做错了什么,请帮助我,谢谢。

我的具体cronjob如下:

0 * * * * { printf "\%(\%Y-\%m-\%d \%H:\%M:\%S)T  Updating Certs\n"; sudo certbot renew  --post-hook "systemctl reload nginx.service postfix.service dovecot.service"; } >> /home/ubuntu/logs/certbot.log

标签: bashubuntucronprintf

解决方案


cron可能会令人惊讶,因为它的工作目录不是$HOME,而且它的默认 shell/bin/sh不是用户 shell。

在编写 crontab 时,您必须记住:

  • 使用完整路径几乎是强制性的。
  • 使用花括号对指令进行分组时{ },必须在最后一条指令的末尾加上分号。
  • 使用 default /bin/shprintf可以限制为 POSIX 功能(这意味着它不会理解%()T构造)。

也就是说,您可以按照以下方式/bin/sh实现您的目的:

0 * * * * { date '+\%Y-\%m-\%d \%H:\%M:\%S  Started Task'; <command>; } >> /full/path/to/log/file

一个完全不同的解决方案是改变你的 crontab 的外壳,就像赛勒斯的回答所暗示的那样。


推荐阅读