ubuntu 为什么我的cron文件中的月度命令不起作用,而日常命令起作用?

niwlg2el  于 2023-10-17  发布在  其他
关注(0)|答案(1)|浏览(105)

我正在管理一个由第三方在Ubuntu操作系统上构建的系统。
在cron文件中有一行代码-每个月的第一天07:00 -应该触发一个bash脚本,该脚本调用一个ansible playbook,并生成一个包含执行信息的日志。
调用链:
cron file -> bash script -> ansible playbook
但这并不起作用:脚本不运行,则不会生成日志。
有什么问题吗?

上下文

cron文件是/etc/cron.d/ansible-cron,case的行是

00 07 1 * * myuser /home/myuser/var/myfolder/ansible-am/collect_sale_statistics.sh >/home/myuser/var/log/collect_sale_statistics-$(date +\%Y-%m).log 2>&1

bash脚本权限为

-rwxr-xr-x 1 myuser myuser 493 Mar 23 17:42 collect_sale_statistics.sh*

其内容是

#!/bin/bash

cd /home/myuser/var/myfolder/ansible-am
/home/myuser/var/myfolder/ansible-venv/bin/ansible-playbook playbooks/collect_sale_statistics/main.yml

在我的机器中,同样的例程被实现为一些成功工作的每日和每周剧本。
例如
cron /etc/cron.d/ansible-cron还包含:

# collect number of reboot in the last week every monday
00 07 * * 1 myuser /home/myuser/var/myfolder/ansible-am/count_reboots.sh >/home/myuser/var/log/count_reboots-$(date +\%w).log 2>&1

bash脚本权限为

-rwxr-xr-x 1 myuser myuser 771 Feb  8  2023 /home/myuser/var/myfolder/ansible-am/count_reboots.sh*

其内容是

#!/bin/bash

cd /home/myuser/var/myfolder/ansible-am
/home/myuser/var/myfolder/ansible-venv/bin/ansible-playbook playbooks/count_reboots.yml

脚本count_reboots.sh运行良好,生成日志,等等。

错误分析

1.关于错误位置

我看到的是没有生成日志,所以我猜测进程在执行cron中的命令之前或之前中断。
所以问题一定出在cron上。
可以肯定的是,它不在Ansible的剧本中。
如果我在终端里手动运行

bash /home/myuser/var/myfolder/ansible-am/collect_sale_statistics.sh

脚本运行正常,只是应该由cron触发的自动执行没有启动。
所以我猜问题出在cron文件和bash脚本的可访问性之间。

2.关于cron语法

我已经在crontab.guru上验证了00 07 1 * *(为collect_sale_statistics.sh设置的cron时间)正确地表示“在第1个月的07:00”。
这个信息有点不清楚,因为“day-of-month 1”可以解释为“day-of-month 1”,也就是1月,所以“every day in January”。
然而,事实并非如此,因为我也在crontab.guru上验证了“一月的每一天”被cron转码为00 07 * 1 *,crontab.guru表示“一月的07:00”。

3.关于cron文件夹

我怀疑问题可能在于我将一个应该每月运行的命令放在一个/etc/cron.d/文件夹中,该文件夹应该专用于包含每天运行的命令的cron文件。
但是,同一个cron文件包含一个每周运行一次的命令,并且运行良好。

xzv2uavs

xzv2uavs1#

正如@GordonDavisson和another SO thread所引用的那样,cron的manpage文档说:

...
Percent-signs (%) in the command, unless escaped with backslash (\), 
will be changed into newline characters, and all data after the 
first % will be sent to the command  as standard input.
...

所以我的台词

00 07 1 * * myuser /home/myuser/var/myfolder/ansible-am/collect_sale_statistics.sh >/home/myuser/var/log/collect_sale_statistics-$(date +\%Y-%m).log 2>&1

将导致

00 07 1 * * myuser /home/myuser/var/myfolder/ansible-am/collect_sale_statistics.sh >/home/myuser/var/log/collect_sale_statistics-$(date +\%Y-
# new line
m).log 2>&1

破解cron文件
在上面的第一行中,我在月份变量的百分比符号(%m)之前添加了一个转义符(\),所以现在它是

00 07 1 * * myuser /home/myuser/var/myfolder/ansible-am/collect_sale_statistics.sh >/home/myuser/var/log/collect_sale_statistics-$(date +\%Y-\%m).log 2>&1

相关问题