在一个项目中,我尝试运行一个命令来处理前一天的数据(一个相当常见的用例)。
我从 Docker 容器(python:3.11 派生)运行它,因此是 Linux 系统,但它不太可能与这个特定系统相关。
为了查找之前的日期,我使用以下命令:
date +%F --date="1 day ago"
+%F
(完整日期)将输出格式设置为YYYY-MM-DD
。
(--date 选项是 Linux 特定的。在 BSD 派生系统(包括 MacOS)上,等效选项是 -v1d)
为了解决这个问题,我准备了一个包含以下任务的小crontab(在我的容器中,它被放在/etc/cron.d/crontab中)
* * * * * root echo "Hello World" 1>> /some/path/log/hello_world.log 2>&1
* * * * * root echo Hello `date` 1>> /some/path/log/hello_today.log 2>&1
* * * * * root echo Hello $(date +%F --date="1 day ago") 1>> /some/path/log/hello_yesterday.log 2>&1
奇怪的是,
hello_world.log
和hello_today.log
可以工作,但hello_yesterday.log
没有创建。
起初我怀疑与命令替换有关的问题,但是第二个任务(
hello_today.log
)有效,并且其内容是正确的。
然后,我想知道这是否可能是命令替换的语法(针对美元括号的反引号),因为旧版本的 shell 不支持美元括号语法。我验证了这两种语法都适用于 hello_today.log
令人兴奋的是第三个任务甚至没有创建日志文件,因此该文件中存储的任何错误消息都没有帮助。就像完全跳过该行一样。
我最终在另一个 Stack Overflow 答案中找到了解决方案 https://stackoverflow.com/a/27125439/11394968[answer][1]
我仍然决定针对这个具体案例分享这个问题/答案,因为它可以帮助其他人。
该问题与 crontab 中的命令替换无关,而仅与百分号有关。它在 crontab 中有特殊含义,在其他命令使用时必须用反斜杠转义。
在这种特定情况下,必须重写任务:
* * * * * root echo Hello $(date +\%F --date="1 day ago") 1>> /some/path/log/hello_yesterday.log 2>&1