find -delete работает нормально, но не с cron

10

ОБРАТИТЕ ВНИМАНИЕ : Я прочитал все подобные вопросы повторно. cron, paths, env-переменные и так далее, но не нашли ни одного, который предлагал бы решения моей конкретной проблемы.


У меня есть скрипт, который делает некоторые дампы MySQL, а затем удаляет старые, как это:

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

( команда выше была изменена из моей первоначальной команды предложениями из комментариев )

Однако файлы никогда не удаляются, когда cron запускает этот скрипт. Пользователь cron - root.

Отладка заметок

  • Если я вручную запускаю сценарий, в котором появляется команда, он удаляет их, как и ожидалось.

  • Если я запускаю указанную выше команду find самостоятельно из командной строки от имени пользователя root, она удаляет их, как и ожидалось (и с параметром -print возвращает список файлов старше 5 дней, как и ожидалось)

  • Я также добавил явную инструкцию path в crontab root, но
    это ничего не меняет.

  • Cron не отправляет сообщение об ошибке, и если я передам операцию поиска в файл журнала, он
    будет пустым или не будет создан вообще.

  • Я использую сервер Ubuntu 14.04.03 LTS.

TommyPeanuts
источник
Я бы избегал подстановочных знаков (например, * .gz) в пути. cron может интерпретироваться как * .gz, не раскрывая все файлы gz.
Archemar
Какой вывод вы получите, если запустите задание без действия/usr/bin/find /home/bkp/dbdump/*.gz -mtime +5
user9517
@Archemar Почему бы не подстановить шаблон? cronКоманды запускаются через оболочку, а оболочка расширяет подстановочные знаки.
Бармар
cronследует отправить письмо с выводом и сообщениями об ошибках. Вы получаете такое письмо от этой работы?
Бармар
@ В общем, все работает как положено.
TommyPeanuts

Ответы:

6

Проблема в том, что crontabне $PATHустановлен во время работы. Вы можете указать путь к нему, добавив его в начало файла, открытого с помощью crontab -e:

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

(или что PATHвы предпочитаете использовать). Это означает, что вы можете не указывать полные пути к командам напрямую из cron.

Есть несколько проблем с вашей исходной командой. Вы в основном просите, чтобы оболочка выполнила расширение подстановочного знака, а не find. Во-вторых, вы не предоставляете полный путь rm; используйте /bin/rmили /usr/bin/rm, где бы он ни находился в вашей системе (см. which rm).

Первый аргумент для поиска - это «местоположение для поиска», а затем вы указываете «поисковый запрос» с различными -<option>s. Итак, правильный формат команды, которую вы хотите выполнить:

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

или

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

Если вы не указали PATHопределение, как указано выше, используйте:

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

или

/usr/bin/find "/home/bkp/dbdump" -name "*.gz" -mtime +5 delete
Будет
источник
1
Он должен был $PATHустановить, но это будет система по умолчанию. Это будет включать /usr/binи /bin, поэтому он должен быть в состоянии найти rmкоманду.
Бармар
Поэтому я попытался поместить $ PATH в crontab (хотя, как упоминалось в другом месте, он, вероятно, по умолчанию использовал бы системный путь, если не указано), и убедился, что у всех есть полные пути. Я также использовал -name "* .gz" вместо подстановочного знака в пути поиска. Но ничего не происходит. Команда, похоже, просто не запускается, и никаких ошибок не выдается.
TommyPeanuts
3

Попробуйте это вместо

find /home/bkp/dbdump -type f -name '*.gz' -mtime +5 -delete
shad0VV
источник
Зачем вам перенаправлять stderr в файл? По умолчанию он будет отправлен по электронной почте, если был какой-либо вывод.
kasperd
Да, это правда, что по умолчанию отправляет любое электронное письмо в спойлер MAIL пользователя и может быть прочитано с помощью почты.
shad0VV
1
Чтобы получить тот же эффект, что и оригинальная команда, вам нужно добавить -maxdepth 1.
Niels Keurentjes
0

Если я вызываю команду find непосредственно из корневого каталога root, а не как часть сценария, то она работает.

Рассматриваемый скрипт использует csh. Я считаю, что среда cron root в Ubuntu будет использовать / bin / bash (или / bin / dash?). Возможно, это как-то противоречит тому, как выполнялась команда find.

В любом случае, главный вопрос решен, хотя и несколько неуверенно.

TommyPeanuts
источник