Автор Тема: Непонятно как работает утилита find. [Решено]  (Прочитано 499 раз)

Оффлайн Nicom

  • Участник
  • *
  • Сообщений: 1 328
На файловом сервере ежедневно, в начале суток, обрабатываются логи и аудиозаписи с телефонных станций, аудио сжимается, каталоги за старые дни удаляются.
Каждый день создаётся подкаталог с вчерашней датой в его имени. В подкаталоге с датой есть свои подкаталоги и отдельные файлы.
В каталоге станции всегда 94 подкаталога.
Всё вроде работает, но cron, запускающий bash-скрипт, присылает письма с примерно следующим содержимым "find: './2026-01-21': No such file or directory".

Единственное место где в скрипте есть find
find . -mtime +93 -exec rm -rf {} \;
Не понимаю, как find не может найти подкаталог если он его удалил, а поскольку он его удалил то зачем ищет повторно?
Что ему действительно не нравится?

В принципе, такое поведение не критично и можно подавить вывод find, или отправку мыла cron-ом, но не хотелось-бы отказываться от писем на случай если что-то действительно пойдёт не так.
« Последнее редактирование: 28.04.2026 07:43:06 от Nicom »

Оффлайн owl5053

  • Участник
  • *
  • Сообщений: 27
find по дефолту обходит дерево каталогов в глубину и даже если удаляется каталог, find уже запланировал проверить его содержимое.
После успешного rm -rf этого каталога find всё равно делает попытку перейти в него и поэтому выходит эта ошибка.

лучше мне кажется использовать -delete:
find . -mtime +93 -delete
почему? потому что "-delete" никогда не пытается зайти в удалённый каталог

Оффлайн Nicom

  • Участник
  • *
  • Сообщений: 1 328
find по дефолту обходит дерево каталогов в глубину и даже если удаляется каталог, find уже запланировал проверить его содержимое.
То есть, он удаляет каталог раньше чем просмотрит его содержимое?
Мне всегда понималось, что сначала find проходит по дереву каталогов, а потом применяет команды вроде -exec и подобных.

лучше мне кажется использовать -delete:
почему? потому что "-delete" никогда не пытается зайти в удалённый каталог
Не знал, проверю завтра.
Спасибо.

Оффлайн Nicom

  • Участник
  • *
  • Сообщений: 1 328
Что find . -mtime +93 -exec rm -rf {} \;, что find . -mtime +93 -delete
работают, как оказалось, одинаково. Всё-равно приходит письмо.

Попробую ограничить уровень вложенности.
find . -maxdepth 1 -mtime +93 -exec rm -rf {} \;Или попробую игнорировать ошибки действия -delete.
find . -ignore_readdir_race -mtime +93 -delete
« Последнее редактирование: 27.04.2026 14:53:36 от Nicom »

Оффлайн rits

  • Участник
  • *
  • Сообщений: 1 475
  • ITS
find /может/полный\ путь/указать?
рискованная команда find . ... rm -rf ...
а без  -mount можно и сетевые шары случайно грохнуть, если таковые будут иметься

Оффлайн owl5053

  • Участник
  • *
  • Сообщений: 27
Что find . -mtime +93 -exec rm -rf {} \;, что find . -mtime +93 -delete
работают, как оказалось, одинаково. Всё-равно приходит письмо.

Попробую ограничить уровень вложенности.
find . -maxdepth 1 -mtime +93 -exec rm -rf {} \;Или попробую игнорировать ошибки действия -delete.
find . -ignore_readdir_race -mtime +93 -delete

вот, блин, тогда так попробуй:
find . -maxdepth 1 -mtime +93 -delete

Оффлайн Nicom

  • Участник
  • *
  • Сообщений: 1 328
find /может/полный\ путь/указать?
рискованная команда find . ... rm -rf ...
Ну, перед find . -mtime... стоит cd /путь/до.файлов/конкретной/атс &&.
Но, спасибо, скрипт поправил, чтобы в find передавался полный путь в цикле.
Из меня тот-ещё писатель, я больше по железякам, отремонтировать там чего.

вот, блин, тогда так попробуй:
Можно и ограничить одной вложенностью с действием -delete, но зачем, если для -delete работает параметр -ignore_readdir_race

Проверять могу одну гипотезу раз в сутки.
На данный момент проверяю find . -maxdepth 1 -mtime +93 -exec rm -rf {} \;  Может добавлю параметр -type d.
Если после этого придёт письмо, то потом проверю find . -ignore_readdir_race -mtime +93 -delete

Оффлайн fraks

  • Участник
  • *
  • Сообщений: 120
Проверять могу одну гипотезу раз в сутки.

Сделай себе скрипт который создает тестовый стенд для проверки как работает find.
Тестовый стенд - это набор файлов и папок с нужными свойствами, имитирующие папки с логами АТС.
Почему не руками сделать стенд? Потому что имея скрипт - для воссоздания стенда достаточно его просто запустить.

Ну и письма дожидаться никакого не надо, просто смотрим вывод команды find.

Оффлайн Nicom

  • Участник
  • *
  • Сообщений: 1 328
Сделай себе скрипт который создает тестовый стенд
Уже сделал.

потому что "-delete" никогда не пытается зайти в удалённый каталог
Действие -delete просматривает каталог перед удалением, потому что по умолчанию включает параметр -depth, судя по man.

Что find . -mtime +93 -exec rm -rf {} \;, что find . -mtime +93 -delete
работают, как оказалось, одинаково. Всё-равно приходит письмо.
Не совсем одинаково. Действие -delete не может удалить непустой каталог и у такого каталога меняется время изменения со всеми вытекающими последствиями.

Проблема решена. Нормально работает конструкция
find /full/path -maxdepth 1 -mtime +93 -exec rm -rf {} \;
« Последнее редактирование: 28.04.2026 07:47:48 от Nicom »

Оффлайн bbc

  • Участник
  • *
  • Сообщений: 6
То есть, он удаляет каталог раньше чем просмотрит его содержимое?
Мне всегда понималось, что сначала find проходит по дереву каталогов, а потом применяет команды вроде -exec и подобных.
Он работает построчно. Можно написать что-то типа:
find /full/path -maxdepth 1 -mtime +93 -delete -or -name total -printТогда первое он будет удалять, а второе - печатать.

Как вариант, помимо глубины можно конвеер использвать:

find /full/path -maxdepth 1 -mtime +93 | xargs rm -rf
Тогда find соберёт все назавния и передаст дальше на удаление. Ошибок быть не должно.