4

I am running this command every hour for cleaning up files:

# crontab -l
MAILTO=notify@localhost
0 */1 * * * find /var/www/tmp/ -name "*" -mmin +60 | /usr/bin/xargs /bin/rm -f -R

But every time the cronjob is executed an email with this error message is sent to my mail account:

/bin/rm: invalid option -- '^M'

Manually executing the command works fine:

find /var/www/tmp/ -name "*" -mmin +60 | /usr/bin/xargs /bin/rm -f -R
# ok

The logs show:

grep CRON /var/log/syslog
Dec 23 06:34:01 Ubuntu-1804-bionic-64-minimal CRON[29314]: (root) CMD (find /var/www/tmp/ -name "*" -mmin +60 | /usr/bin/xargs /bin/rm -f -R --^M)

So apparently the problem is in the cron file.

Regards,

5
  • 2
    Looks like one of the files in /var/www/tmp has a control character in it's name. You may want to add double dash -- to rm to signify end of args or use -print0 in find with -0 in xargs. As for how that control character got there into filename - might be something else to consider. If files in that folder have any interaction with external world, I'd be very suspicious as to whether someone is messing with your web server Dec 23, 2019 at 5:17
  • Thanks for your answer. But why does the command only fail when ran as a cronjob?
    – Hyndrix
    Dec 23, 2019 at 5:28
  • 9
    Wait a second. ^M that's a carriage return. When you wrote that cron job, were you using any Windows-specific utilities ? See unix.stackexchange.com/questions/32001/… Dec 23, 2019 at 5:45
  • 1
    Note this will fail in unexpected and wonderful ways if your file names have spaces etc. See the -exec and -delete options on find or the -print0 option to output items delimited with the null character. Dec 23, 2019 at 16:34
  • BTW, -name "*" does nothing and can be left out. Dec 24, 2019 at 18:04

2 Answers 2

15

It sounds like there may be a carriage return at the end of the line in your crontab file (^M is sometimes output by non-carriage-return-friendly programs). You could confirm this by:

cat -v /var/spool/cron/crontabs/{user}

Be sure to substitute {user} with your username. If you see ^M in the output, then there are carriage returns in the file. They can be removed with a program like sed (be sure to backup the file first):

sed -i 's/\r//' /var/spool/cron/crontabs/{user}'

As mentioned in a comment from Lightness Races by Monica, dos2unix is also a good option for removing carriage returns from text files.

The default for dos2unix is to overwrite the file in-place, so after backing up the file:

dos2unix /var/spool/cron/crontabs/{user}
1
6

Thanks to Sergiy Kolodyazhnyy' hint I found out that all crontabs end with the control charater. I then cleaned and reentered the commands and now it works:

crontab -l
crontab -e # enter commands here again

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.