Issue
I am managing a system built by third parts on a Ubuntu OS.
There is a line in a cron file which - every first day of the month at hour 07:00 - should trigger a bash script which calls an ansible playbook, and produce a log with the information about the execution.
chain of calls:
cron file -> bash script -> ansible playbook
However this does not work: the script does not run, the log does not get generated.
What is the problem ?
Context
The cron file is /etc/cron.d/ansible-cron
, and the line of the case is
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
the bash script permissions are
-rwxr-xr-x 1 myuser myuser 493 Mar 23 17:42 collect_sale_statistics.sh*
and its content is
#!/bin/bash
cd /home/myuser/var/myfolder/ansible-am
/home/myuser/var/myfolder/ansible-venv/bin/ansible-playbook playbooks/collect_sale_statistics/main.yml
In my machine, the same routine is implemented for some daily and weekly playbooks which successfully work.
e.g.
The cron /etc/cron.d/ansible-cron
also contains:
# 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
the bash script permissions are
-rwxr-xr-x 1 myuser myuser 771 Feb 8 2023 /home/myuser/var/myfolder/ansible-am/count_reboots.sh*
and its content is
#!/bin/bash
cd /home/myuser/var/myfolder/ansible-am
/home/myuser/var/myfolder/ansible-venv/bin/ansible-playbook playbooks/count_reboots.yml
The script count_reboots.sh
runs fine, the log is generated, etc.
error analysis
1. About the error location
What I see is that the log was not generated, so I guess that the process breaks before when or before the command in the cron is executed.
So the problem must be in the cron.
For sure it is not in the ansible playbook.
If I manually run in the terminal
bash /home/myuser/var/myfolder/ansible-am/collect_sale_statistics.sh
the script runs fine, just the automatic execution which should be triggered by the cron does not start.
So I guess the problem lies somewhere between the cron file and the accessibility to the bash script.
2. About the cron syntax
I have verified on crontab.guru that 00 07 1 * *
( the cron time set for collect_sale_statistics.sh
) correctly means "At 07:00 on day-of-month 1."
This message is slightly unclear, as "day-of-month 1" could be interpreted as "day-of month1", which is January, so "every day in January".
However, this is not the case, as I have also verified on crontab.guru that "every day in January" is cron-transcoded as 00 07 * 1 *
, for which crontab.guru indicates "At 07:00 in January.".
3. About the cron folder
I suspect the problem might be in the fact that I am placing a command which is supposed to run monthly in a folder /etc/cron.d/
which should be dedicated to cron files which should contain comands to be run daily.
However, the same cron file contains a command which is run weekly, and it runs fine.
Solution
As quoted by @GordonDavisson and by another SO thread, the manpage documentation for cron says:
...
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.
...
so my line
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
would result in
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
and break the cron file.
In the first line above, I have added an escape (\
) character before the percent sign of the month variable (%m
), so now it is
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
Answered By - Tms91 Answer Checked By - Mildred Charles (WPSolving Admin)