8

PLEASE NOTE: I have read all the similar questions re. cron, paths, env variables and so on, but have found none that offer solutions to my particular problem.


I have a script that makes some MySQL dumps and then deletes old ones like this:

/usr/bin/find "/home/bkp/dbdump" -name "*.gz" -mtime +5 -delete

(above command has been modified from my original command by suggestions from comments)

However, the files are never deleted when cron runs this script. The cron user is root.

Debugging notes

  • If I manually run the script in which the command appears, it deletes them as expected.

  • If I run the above find command on its own from the command line as root, it deletes them as expected (and with -print it returns a list of files older than 5 days as expected)

  • I have also added an explicit path statement to root's crontab, but
    that doesn't change anything.

  • Cron sends no error, and if I pipe the find operation to a log file,
    that comes up empty or is not created at all.

  • I'm using Ubuntu server 14.04.03 LTS.

  • I would avoid wildcard expansion (e.g.*.gz) in path. cron might interpret as *.gz, not expanding all gz files. – Archemar Dec 13 '15 at 10:11
  • What output do you get if you run the job without an action /usr/bin/find /home/bkp/dbdump/*.gz -mtime +5 – Iain Dec 13 '15 at 10:54
  • @Archemar Why wouldn't the wildcard get expanded? cron commands are run through the shell, and the shell expands wildcards. – Barmar Dec 16 '15 at 7:02
  • cron should send email with output and error messages. Do you get any such email from this job? – Barmar Dec 16 '15 at 7:04
  • @Iain it works as expected. – TommyPeanuts Dec 18 '15 at 5:44
7

The problem is that crontab doesn't have $PATH set when it runs. You can actually provide it with a path by adding this to the top of the file opened via crontab -e:

PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

(or whatever PATH you'd prefer to use). This means you can avoid specifying the full paths to commands, directly from cron.

There are multiple problems with your original command. You're basically asking the shell to do the wildcard expansion, rather than find. Secondly, you're not providing a full path for rm; use /bin/rm or /usr/bin/rm, wherever it's located on your system (see which rm).

The first argument for find is the "location to search", and then you specify the "search query" with the various -<option>s. So, the proper format of the command you want to run is:

find "/home/bkp/dbdump" -name "*.gz" -mtime +5 -exec rm -f {} \;

or

find "/home/bkp/dbdump" -name "*.gz" -mtime +5 delete

If you don't specify the PATH definition like above, use:

/usr/bin/find "/home/bkp/dbdump" -name "*.gz" -mtime +5 -exec /bin/rm -f {} \;

or

/usr/bin/find "/home/bkp/dbdump" -name "*.gz" -mtime +5 delete
  • 1
    It should have $PATH set, but it will be the system's default. This will include /usr/bin and /bin, so it should be able to find the rm command. – Barmar Dec 16 '15 at 7:01
  • So I tried putting $PATH in the crontab (although as mentioned elsewhere it would probably default to the system path if not stated), and made sure everything had full paths. I also used -name "*.gz" instead of a wildcard on the find path. But nothing happens. The command just doesn't seem to run and there are no errors thrown. – TommyPeanuts Dec 19 '15 at 10:32
3

Try this instead

find /home/bkp/dbdump -type f -name '*.gz' -mtime +5 -delete
  • Why would you redirect stderr to a file? By default it will be send by email if there was any output. – kasperd Dec 13 '15 at 10:04
  • Yes it is true that by default is sending any email to the spooler MAIL of the user and can be read using mail. – shad0VV Dec 13 '15 at 10:13
  • 1
    To get the same effect as the original command you would need to add -maxdepth 1. – Niels Keurentjes Dec 14 '15 at 7:40
0

If I invoke the find command directly from root's crontab and not as part of the script, then it works.

The script in question uses csh. I believe that root's cron environment on Ubuntu will be using /bin/bash (or /bin/dash?). Perhaps this conflicts in some way with how the find command was running.

Either way, the main issue it solved, albeit somewhat inelegantly.

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.