Назад | Перейти на главную страницу

Использование `find` для удаления

Итак, учитывая три варианта ...

  1. find .... -delete
  2. find .... | xargs rm ...
  3. find .... -exec rm ...;

..или их варианты, какой вариант предпочтительнее?
Я предполагаю, что нет однозначного и быстрого ответа, и конкретная ситуация подскажет лучший вариант (пожалуйста, назовите их!)

Ура.

Вариант 1 позволит избежать появления внешних процессов, что полезно в стрессовых условиях.

Вариант 2 создаст сингл xargs процесс, который будет порождать только столько rm обрабатывает по мере необходимости. Этот параметр обычно используется с -print0 и -0 для обработки имен файлов с пробелами и / или символами новой строки.

Вариант 3 создаст rm процесс для каждого файла.

GNU find (или любая POSIX-совместимая версия find) допускает четвертый вариант, find .... -exec rm -r {} +, который будет работать rm с максимально возможным количеством имен файлов, чтобы порождать только ограниченное их количество.

Я предпочитаю использовать find ... > file.txt внимательно просмотрите файл, затем используйте find ... -delete поэтому я знаю, что те же самые результаты будут удалены (передаваемые аргументы в основном пуленепробиваемые).

Тема удаления файлов рассматривается в разделе «Очистка» документации GNU findutils. Вы можете прочитать это в своей системе с помощью «info find» или в Emacs. Вы также можете просмотреть его в Интернете по адресу http://www.gnu.org/software/findutils/manual/html_node/find_html/Cleaning-Up.html#Cleaning-Up.

find .... -delete

Это наиболее безопасный (против гонок символических ссылок) и высокопроизводительный (поскольку нет необходимости выполнять что-либо или переключать контекст, когда буфер канала заполнен). Но имейте в виду, что -delete подразумевает -depth.

find .... | xargs rm ...

Это опасно в ситуациях, когда у других есть доступ на запись к дереву, в котором вы выполняете очистку. Например, предположим, что команда find решила, что /var/tmp/scratch/me/.ssh/config соответствует ее требованиям, и поэтому печатает эти имена в стандартный вывод. Команда xargs прочитает это и добавит в структуру данных. Через некоторое время (когда xargs прочитает количество байтов, указанное значением по умолчанию для параметра -s) xargs выполнит fork и выполнит rm, чтобы удалить его. Однако возможно, что тем временем это сделал кто-то другой:

$ cd /var/tmp/scratch
$ mv me me.old
$ ln -s /root me

Затем, когда rm удалит /var/tmp/scratch/me/.ssh/config, он выдаст системный вызов unlink ("/ var / tmp / scratch / me / .ssh / config"). Поскольку ядро ​​разрешит символическую ссылку за вас, это эквивалентно вызову unlink ("/ root / .ssh / config"). Если процесс xargs выполнялся от имени пользователя root, то /root/.ssh/config будет удален, несмотря на то, что вы не указали -L в командной строке. По этой причине, если важна безопасность, используйте -delete. Вы можете прочитать больше об этой области в разделе «Вопросы безопасности» руководства GNU find.

find .... -exec rm ...;

Поскольку здесь также задействованы fork / exec, возникают те же проблемы безопасности, о которых я упоминал выше.

Короче говоря, единственная причина не использовать -delete - совместимость с системами, в которых отсутствует поддержка -delete.