Форум русскоязычного сообщества Ubuntu


Автор Тема: find ругается, что не может найти то, что сам же нашел и удалил  (Прочитано 2100 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн 027

  • Автор темы
  • Участник
  • *
  • Сообщений: 108
  • Cinnamon
    • Просмотр профиля
# find /backup/mysql/ -type d -mtime +10 -exec rm -rf {} \;
find: «/backup/mysql/2017-05-19»: Нет такого файла или каталога
find: «/backup/mysql/2017-05-16»: Нет такого файла или каталога
find: «/backup/mysql/2017-05-15»: Нет такого файла или каталога
find: «/backup/mysql/2017-05-18»: Нет такого файла или каталога
find: «/backup/mysql/2017-05-12»: Нет такого файла или каталога
find: «/backup/mysql/2017-05-20»: Нет такого файла или каталога
find: «/backup/mysql/2017-05-14»: Нет такого файла или каталога
find: «/backup/mysql/2017-05-17»: Нет такого файла или каталога
find: «/backup/mysql/2017-05-13»: Нет такого файла или каталога
find: «/backup/mysql/2017-05-21»: Нет такого файла или каталога
find: «/backup/mysql/2017-05-22»: Нет такого файла или каталога
Точный список того, что было удалено этой командой.
То ли лыжи не едут, то ли...  :idiot2:
Если бы было достаточно man bash, не было бы ABS.

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2628
    • Просмотр профиля
А если так:
find /backup/mysql -mindepth 1 -type d -mtime +10 -exec rm -rf "{}" \;?
« Последнее редактирование: 02 Июнь 2017, 11:59:51 от renzrv »

Оффлайн symon.2014

  • Забанен
  • Старожил
  • *
  • Сообщений: 1225
  • Ковырятель страны OS.
    • Просмотр профиля
То ли лыжи не едут, то ли...
sudo updatedb

Оффлайн 027

  • Автор темы
  • Участник
  • *
  • Сообщений: 108
  • Cinnamon
    • Просмотр профиля
А если так:
То же самое. Равно, как и с одинарными кавычками.

updatedb
а это к чему?

man updatebd:
Цитировать
updatedb  creates  or updates a database used by locate(1).
Про find там ни слова.
Если бы было достаточно man bash, не было бы ABS.

Оффлайн Azure

  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 6015
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
find /backup/mysql/ -depth -type d -mtime +10 -exec rm -rf {} +Хотя зачем городить огород?find /backup/mysql/ -type d -mtime +10 -delete
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн 027

  • Автор темы
  • Участник
  • *
  • Сообщений: 108
  • Cinnamon
    • Просмотр профиля
Хотя зачем городить огород?
Это я и пытался сразу, однако ругается на непустые директории.
А вот замена \; на плюс помогла, причем наличие -depth не влияет.
Ничего не понял в этой магии, но хоть выхлоп очистился.
Спасибо за помощь обутому в лыжи.
Если бы было достаточно man bash, не было бы ABS.

Оффлайн soarin

  • Старожил
  • *
  • Сообщений: 1792
  • ubuntu 20.04
    • Просмотр профиля
Так оно первым находит директорию /backup/mysql/ и всю её удаляет рекурсивно (-rf)
find /backup/mysql/ -type d -mtime +10 -exec echo {} \;
« Последнее редактирование: 02 Июнь 2017, 20:08:34 от soarin »

Оффлайн 027

  • Автор темы
  • Участник
  • *
  • Сообщений: 108
  • Cinnamon
    • Просмотр профиля
Смелая гипотеза, но неверная.
Он удаляет только поддиректории по приведенному выше списку. После чего приводит его же в качестве недоступного. После.
Остальные (которые моложе -mtime +10) остаются (т.е. в принципе делает именно то, что надо, вот только ругательства в std_error смущают).
Если бы было достаточно man bash, не было бы ABS.

Оффлайн Azure

  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 6015
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
находит директорию /backup/mysql/ и всю её удаляет рекурсивно
Теоретически да, но поскольку время изменения директории == времени самого нового файла/директории, то если есть субдиректории/файлы не удовлетворяющие -mtime +10 то и корневая не будет выбрана, но лучше использовать -mindepth 1
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн 027

  • Автор темы
  • Участник
  • *
  • Сообщений: 108
  • Cinnamon
    • Просмотр профиля
если есть субдиректории/файлы не удовлетворяющие -mtime +10 то и корневая не будет выбрана, но лучше использовать -mindepth 1
Спасибо за уточнение, так, действительно, надежнее. Оно, конечно, крайне маловероятно, чтобы корневая из-за какого-то глюка внезапно получила старое mtime, но исключить и это, как-то спокойнее. :)
В общем, сделал так, как с самого начала надо было:
find /backup/mysql/*(я отчего-то думал, что завершающего слэша будет достаточно)
Без -mindepth 1, понятно.
С магией после -exec разобрался более-менее, поставив echo вместо rm:
find /backup/mysql/* -type d -mtime +10 -exec echo {} и далее пробуем \; ';' или +.Точка с запятой организует цикл вызова команды с подстановкой вместо {} очередного единичного результата поиска, а плюсик вываливает туда сразу все найденное через пробел. Что есть хорошо и правильно для команд типа rm, принимающих сразу пачку аргументов через пробел.

И, что очень странно, при наличии цикла с семиколоном, find сначала скармливает найденное, а потом зачем-то проверяет его наличие ПОСЛЕ отрабатывания вызванной команды. Иначе как объяснить его ругательства на невозможность найти им же найденное и удаленное с его подачи?

Видимо, для столь почтенной утилиты это не баг, это фича. Как для крона необходимость человеку помнить-не-забыть вставить перевод строки в конце, а то ведь кронтаб -е даже не почешется, зараза. :)
Если бы было достаточно man bash, не было бы ABS.

Оффлайн Azure

  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 6015
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
find сначала скармливает найденное, а потом зачем-то проверяет его наличие ПОСЛЕ отрабатывания вызванной команды. Иначе как объяснить его ругательства на невозможность найти им же найденное и удаленное с его подачи?
Если Вы внимательно прочитаете man find
Код: HTML5
  1.        If the whole expression contains no actions other than -prune or -print, -print is performed on all files for which
  2.        the whole expression is true.
  3.  
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн 027

  • Автор темы
  • Участник
  • *
  • Сообщений: 108
  • Cinnamon
    • Просмотр профиля
Я это читал, но понять это не с моим зачаточным уровнем английского, прошу простить. Из сего текста разве следует, в какой последовательности что делается? Я этого не понял. Метод организованного тыка показал — в неожиданной для меня последовательности. К тому же проверка существования файла выполняется два раза — ведь сначала надо его найти (нельзя же найти несуществующее?), потом передать rm, потом снова проверить его существование.
А что такое whole expression? Вернее, где его конкретные рамки, «всего выражения»?
И — почему тогда не выполняется -print после -exec echo? Почему нет сдвоенной печати?

(это все не полемики ради, просто не понимаю логики автора утилиты)
« Последнее редактирование: 05 Июнь 2017, 21:46:58 от 027 »
Если бы было достаточно man bash, не было бы ABS.

Оффлайн Azure

  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 6015
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Всё — это все, какие «границы»?
contains no actions
не содержит никаких действий отличных от -prune or -print, то выполняется -print. По большому счету -exec тоже действие, но тут зависит от конкретных реализаций.
Но в Вашем конкретном случае логика другая: Команда обнаружив директорию согласно Вашей инструкции удаляет её, но поскольку она (была) не пустая — пытается прочитать ее подуровни, а её уже нет. Решать можно несколькими путями(опциями) и/или их комбинацией:
  • -depth начинать обработку с нижнего уровня вложенности
  • -prune не входить «внутрь» найденных директорий
  • -maxdepth 1 ограничить поиск первым под-уровнем
  • + сначала собрать все аргументы(закончить поиск), а потом приступить к удалению
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн 027

  • Автор темы
  • Участник
  • *
  • Сообщений: 108
  • Cinnamon
    • Просмотр профиля
Всё — это все, какие «границы»?
В программировании у выражения границы есть всегда. И какие именно имеются в виду в сложной строчной команде, так просто не скажешь. Вплоть до терпеливого вдумчивого анализа исходников и проведения тестов. Это самое «всё» может оказаться очень даже разным, а еще всякие дефолты.
Но в Вашем конкретном случае логика другая: Команда обнаружив директорию согласно Вашей инструкции удаляет её, но поскольку она (была) не пустая — пытается прочитать, а её уже нет.
Воот. Именно этой логики я не понимаю.
Команда — это find, она ничего не удаляет (мы же не использовали - delete, правда?)
А вот то, что сначала отдает имя другой команде, а только потом идет дальше — воот, теперь у меня проясняется. Я, по наивности, полагал, что сначала найдем все, а потом уж будем решать, что с этим делать.
Списки там, массивы...
А оказывается, немедленная реакция на выдачу имени и запуск внешней команды, безо всякого опасения, что она может наделать с этим файлом. И только потом потом попытка работать с этим файлом, оказавшимся внезапно директорией.

Спасибо за разъяснение. Из той строчки в мане я в жизни бы такое «тупое» поведение не вывел. Такой умной утилиты.



Пользователь добавил сообщение 05 Июнь 2017, 23:24:42:
+ сначала собрать все аргументы(закончить поиск), а потом приступить к удалению
Тут я не совсем могу согласиться, а именно насчет удаления. Там ключ -exec, т.е. тупо передать данные внешней команде. Что там она будет вытворять, find понятия не имеет.

Но. Теперь стало понятнее.
find не умеет цикл типа for in, как мне было померещилось.
Либо он в цикле дергает внешнюю команду, а потом, в той же итерации, выплняет дефолтное действие (углубление вниз по дереву, вот где моя ошибка/непонимание).
Либо (с модификатором +) сначала пройтись по всему древу, собрать найденные имена в строку через пробел (о, этот юниксвэй со святой верой в пробелы...) и скормить, что получится, однократно, внешней команде.

Спасибо за пинки, уже который раз помогаете понять.
« Последнее редактирование: 05 Июнь 2017, 23:29:24 от 027 »
Если бы было достаточно man bash, не было бы ABS.

Оффлайн Azure

  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 6015
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Тут я не совсем могу согласиться, а именно насчет удаления. Там ключ -exec, т.е. тупо передать данные внешней команде. Что там она будет вытворять, find понятия не имеет.
Ну рассматривался конкретный пример, поэтому удаление.
find не умеет цикл типа for in, как мне было померещилось.
Из чего это следует? Читайте все что Вам пишут, а не выборочно. Нашла элемент, определила что это директория, на следующей итерации запланировало вход в нее, отдала в -exec, перешла к следующей итерации, а директории уже нет.
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

 

Страница сгенерирована за 0.227 секунд. Запросов: 25.