102

The following command works from prompt but not from crontab.

 grep abc  /var/log/messages | grep "`date '+%B %d'`" | mail -s"abc log of `hostname`" s.o+`hostname`@gmail.com

I need to add it to daily cron.

shantanuo
  • 3,459
  • 8
  • 47
  • 64
  • 1
    Your example is amazing, the % is surrounded by double, simple and back quotes. Leaving no hope that quote escaping could work. – tuxayo Jan 26 '18 at 16:39

2 Answers2

171

You have to escape the % signs. They have a special meaning in crontabs:

man (5) crontab:

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.
bmk
  • 2,239
  • 2
  • 15
  • 10
  • 9
    Well I just did run into this. I was using `date +%F` and was getting nowhere – adamo Feb 20 '15 at 12:14
  • 5
    Does this syntax have any useful use? With `SHELL=/bin/bash`, I can always rewrite `cat %Hello world` as `cat <<<'Hello world'`. I do not see the need for special syntax. – Witiko Jul 19 '17 at 13:54
  • @Witiko If the "special syntax" you're asking about is the backslash to escape percent, then the OP's own question is an example where it's needed: command arguments that require percent, notably the date program, which would be quite popular in a crontab command. If you're actually asking why cron has this gotcha in the first place: ie: substitutes linefeed in place of percent, then I guess it's so you can supply, on a single line that crontab requires, a "command" that consist of two or more subsidiary commands. – gwideman Sep 06 '18 at 03:57
  • 1
    The latter. And, as I mentioned, one can do the same with bash. No need to litter the syntax of Cron. – Witiko Sep 06 '18 at 11:11
8

This doesn't directly answer your question, but I would suggest that you create a script file in /usr/local/bin (or ~/bin or whatever is appropriate) and call that from cron. It's easier to test and edit.

Randy Orrison
  • 490
  • 6
  • 11
  • 6
    In my experience, it is much easier to maintain 50 lines in a crontab than it is to maintain 50 tiny files. You will want to turn longer scripts into script files for sure, but doing so for one-liners may be an overkill. – Witiko Oct 03 '17 at 00:13