Cron: Why % Breaks Your Cron Command
In a crontab line, a percent sign % is special: the first % ends the command and everything after it is passed to the command as standard input, with each % becoming a newline. To use % literally (e.g. date +%Y-%m-%d) you must escape every one as \%.
What goes wrong
This line looks fine but fails:
0 0 * * * echo $(date +%Y-%m-%d) >> /var/log/job.log
Cron turns the %Y, %m, %d percent signs into newlines, so date receives a broken format and the rest of the line is treated as stdin.
The fix: escape every %
0 0 * * * echo $(date +\%Y-\%m-\%d) >> /var/log/job.log
Each \% is passed to the shell as a literal %.
Cleaner: put it in a script
Move the command into a shell script and call the script from cron. Inside a script file the % is not special, so no escaping is needed — this is the most reliable fix and keeps crontab lines short.
FAQ
Why does my cron job with date +%Y fail?
Cron treats % as special: the first % ends the command and later % become newlines. Escape each as \% or move the command into a script.
How do I use a percent sign in crontab?
Escape it with a backslash: write \% for every literal % you need, for example date +\%Y-\%m-\%d.
Does the % rule apply inside a script called by cron?
No. The % is only special on the crontab line itself. Inside a shell script referenced by cron you can use % normally.