bash - 使用 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
解决方案
cron可能会令人惊讶,因为它的工作目录不是$HOME
,而且它的默认 shell/bin/sh
不是用户 shell。
在编写 crontab 时,您必须记住:
- 使用完整路径几乎是强制性的。
- 使用花括号对指令进行分组时
{ }
,必须在最后一条指令的末尾加上分号。 - 使用 default
/bin/sh
,printf
可以限制为 POSIX 功能(这意味着它不会理解%()T
构造)。
也就是说,您可以按照以下方式/bin/sh
实现您的目的:
0 * * * * { date '+\%Y-\%m-\%d \%H:\%M:\%S Started Task'; <command>; } >> /full/path/to/log/file
一个完全不同的解决方案是改变你的 crontab 的外壳,就像赛勒斯的回答所暗示的那样。
推荐阅读
- angular - 在Angular中添加新记录时如何自动将新记录显示到列表中?
- javascript - 从文本中的字符中删除字符串中的所有 \n
- r - 如何使用过滤器功能来提高样品均质性?
- c++ - TLE 中的 Hashmap 优化结果
- html - 用于 IMG 标签的 Contenteditable insertHTML 命令去除了一些样式属性
- angular - 使用 1 个 S3 存储桶和 1 个 CloudFront 托管多个 Angular 应用程序
- pdf - 签名的 PDF 未准备好 LTV
- javascript - 如果对象包含值,我如何添加特定对象?
- .net-core - 如何将 dotnet 6 预览版降级为 dotnet 5?
- unity3d - 通过后端取消用户订阅