You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Crontab中使用printf打印时间报invalid directive错误如何解决

问题根源

  1. Shell不兼容:Ubuntu系统的crontab默认使用/bin/sh(指向dash)作为执行shell,%()T是bash内置printf的扩展日期格式指令,dash的printf不支持该语法,因此会报invalid directive错误。你在终端执行正常是因为终端默认使用bash作为交互shell。
  2. 你已经做了%符号的转义,这部分操作是正确的,问题不在这里。

解决方法

有三种常用的可行方案,按需选择即可:

方案1:指定crontab使用bash作为默认shell

在你的crontab配置最顶部添加一行声明:

SHELL=/bin/bash

之后你的原有任务配置只需额外添加错误输出重定向即可正常运行:

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 2>&1

方案2:显式调用bash执行任务

不想修改crontab全局shell的话,可以直接把命令包裹在bash调用中:

0 * * * * /bin/bash -c '{ 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 2>&1

方案3:用date命令替代printf的日期格式化(兼容性最优)

如果不想依赖bash特性,直接用date命令输出时间,兼容所有shell,不需要修改默认shell配置:

0 * * * * { echo "$(date +"\%Y-\%m-\%d \%H:\%M:\%S")  Updating Certs"; sudo certbot renew --post-hook "systemctl reload nginx.service postfix.service dovecot.service"; } >> /home/ubuntu/logs/certbot.log 2>&1

额外优化建议

如果这个任务是写在普通用户的crontab里,需要确保当前用户执行certbot和systemctl reload的sudo操作不需要输入密码,否则任务会执行失败。更推荐把这条定时任务写到root用户的crontab中(执行sudo crontab -e编辑),去掉命令中的sudo前缀即可,权限更合理也不需要额外配置sudo规则。

内容的提问来源于stack exchange,提问作者Ajay Varghese

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 02:18:03