Using printf to print out the time before running a program in Crontab giving an "invalid directive" error

Viewed 254

I am running Ubuntu 21.10 and trying to setup a crontab task.

I want the date and time to be printed to the console before the task starts all of which get's logged to a log file.

This is what I have currently.

{ printf "\%(\%Y-\%m-\%d \%H:\%M:\%S)T  Started Task\n"; <run task> } >> /path/to/log/file

When I type printf "%(%Y-%m-%d %H:%M:%S)T Started Task\n" I get the expected output:

2021-10-20 15:22:03 Started Task

However, in the crontab I know you have to escape out the "%" with \. Except even after escaping out all the % I end up with a error :

/bin/sh: 1: printf: %(: invalid directive

No matter how a try and format the crontab I still end up with the same error.

If anyone know what I have done wrong please help me, thank you.

My specific cronjob is as follows:

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 Answers

cron can be surprising because its working directory is not $HOME and its default shell is /bin/sh instead of the user shell.

While writing your crontab, you have to keep in mind that:

  • Using full-paths is almost mandatory.
  • When grouping instructions with curly-brackets { }, you must put a semi-colon at the end of the last instruction.
  • With the default /bin/sh, printf can be limited to POSIX features (which means that it'll not understand the %()T construct).

That said, here's how you can make do of /bin/sh for your purpose:

0 * * * * { date '+\%Y-\%m-\%d \%H:\%M:\%S  Started Task'; <command>; } >> /full/path/to/log/file

A completely different solution is to change your crontab's shell, like Cyrus's answer is suggesting.

Your cron uses sh as shell. Your code (printf with feature T) expects bash (version >= 4.2). I suggest to add this in a separate line before your cronjob to force bash as shell.

SHELL=/bin/bash
Related