Почему «find . -name somedir -exec rm -r {} ;» выходит ненулевым всякий раз, когда он успешно удаляет каталог?

#bash

#bash

Вопрос:

Я хочу найти папку в известной папке, но с неизвестным точным путем, поэтому я должен использовать find . Когда я нахожу его, я использую -exec, чтобы удалить его, но я не могу оценить, удалось ли это. Поведение меня несколько смущает; если я не нахожу папку, я получаю код возврата 0:

 >find . -name "testuuu" -exec rm -r {} ;
find: ‘./.docker’: Permission denied
>echo $?
0
  

Но когда я нахожу папку и удаляю ее, она возвращает код ошибки 1:

 > find . -name "test" -exec rm -r {} ;
find: ‘./.docker’: Permission denied
find: ‘./test’: No such file or directory
> echo $?
1
  

Это ожидаемое поведение? Почему?
Кроме того, как я могу получить код возврата «rm», а не «find», и, таким образом, оценить, была ли папка удалена?

Комментарии:

1. Использование -exec rm -r ... не обязательно приведет только к одному коду возврата, поэтому вам следует подумать о другом подходе, возможно, с использованием скрипта. Вы можете найти этот ответ на аналогичный вопрос в Unix и Linux полезным.

2. From man find : «поиск завершается со статусом 0, если все файлы обработаны успешно, больше 0, если возникают ошибки. Это намеренно очень широкое описание, но если возвращаемое значение не равно нулю, вам не следует полагаться на корректность результатов find . »

3. Однако я не понимаю, почему здесь произошла ошибка. Файл был найден и успешно удален.

4. … а затем find сбой при попытке возврата в каталог после того, как он больше не существовал. Вам нужно сообщить ему, чтобы он изменил порядок операций (чтобы выполнять действия с каталогами только после работы с их дочерними элементами), если вы не хотите этой проблемы.

Ответ №1:

Используйте -depth опцию, чтобы заказать обход в глубину — таким образом find , вы не пытаетесь найти что-либо в вашем каталоге после того, как каталог уже удален (операция, которая по своей природе всегда завершается неудачей).

 find . -depth -name "test" -exec rm -r -- '{}' ;
  

Эта опция также включена по умолчанию, когда вы используете -delete действие в GNU find для удаления содержимого.


Кстати, если test каталогов много, вы могли бы повысить производительность, сделав это -exec rm -r -- {} (которое передает каждой копии rm столько имен файлов, сколько поместится в его командной строке) вместо -exec rm -r -- {} ; (который запускает новую копию rm для каждого test найденного), за счет того, что больше не собирает отдельныекоды ошибок.