знайти - exec rm vs -delete


260

Я намагаюся зрозуміти різницю між цими двома командами:

sudo find / -name .DS_Store -delete

і

sudo find / -name ".DS_Store"  -exec rm {} \;

Я помітив, що execметод є кращим. Чому? Який безпечніший / швидший / кращий? Я використовував обидва на своєму Macbook, і все, здається, працює добре.

Відповіді:


245

-delete буде краще, тому що не потрібно породити зовнішній процес для кожного відповідного файлу.

Можливо, що ви можете бачити -exec rm {} \;часто рекомендовані, оскільки -deleteіснує не у всіх версіях find. Я зараз не можу перевірити, але я впевнений, що findбез цього користувався.

Обидва методи повинні бути "безпечними".

EDIT на коментар від @doitmyway: переконайтеся , що ви підходите на ім'я і потім видалити, а не навпаки (видалити, а потім збігаються). Інакше кожен файл буде видалений, збігається він чи ні . Тобто, НЕ робити цього: find / -delete -name .DS_Store.

Загальний метод уникнення накладних нересту зовнішнього процесу для кожного зібраного файлу:

find / -name .DS_Store -print0 | xargs -0 rm

(але зауважте, що тут є і проблема з портативністю: не всі версії пошуку є -print0!)


2
Я бачу. Я також читав, що за допомогою -deleteперемикача перед -nameвидаленням вказаного дерева файлів, тому, мабуть, я повинен бути обережним.
Цибуля

8
Останнє findви можете використовувати -exec rm {} +для видалення всіх збігаються файлів за допомогою однієї rmкоманди.
jimmij

3
.DS_Storeвзагалі не містить спеціальних символів, тому лапки є непотрібними і нічого не змінюють у цьому випадку.
Целада

1
По суті, лише пробіли (пробіли, вкладки, можливо, інші) - це єдине, що спричинює інтерпретацію рядка без котирування як два окремі аргументи командного рядка, але це ще не все, про що ви повинні шкодувати, вирішуючи, цитувати чи ні. Вам доведеться турбуватися про всі метахарактори оболонки, такі як ;або |або >або <та `` та багато інших, які мають спеціальне значення для оболонки, якщо не цитується.
Целада

1
@MarcoMarsala прозоро xargsпереймається проблемою списку аргументів обмеженого розміру, розбиваючи її на кілька викликів команди.
Селада

27

Якщо припустити, що .DS_Storeпредставляють файли, а не каталоги, самим швидким способом зробити це було б:

sudo find / -name .DS_Store -exec rm {} +

Єдиний ризик - sudoнедоступність, але сьогодні вона є досить низькою.

-deleteПараметр , який використовується , щоб зажадати GNU знайти і до сих пір не стандарт у багатьох інших findреалізаціях, тому не завжди доступний.

Закінчення команди +замість \;сильно оптимізує execпункт, не виконуючи rmкоманди для кожного .DS_Storeприсутнього у файловій системі.


16

У такій машині, як ваш macbook, ви не знайдете великої різниці у продуктивності між двома командами. Однак, якщо ви подивитесь на версію -exec, ви можете побачити тонку різницю:

sudo find / -iname ".file-to-delete"  -exec rm {} \;

Це означає, що ви знайдете всі ці файли з назвою ".file-to-delete". Однак цей пошук може повернути небажані помилкові позитиви. Роблячи щось із судо, ви повинні бути трохи обережнішими. Перевага використання -exec rm {} полягає в тому, що ви можете передавати аргументи в rm так:

sudo find / -iname "*~"  -exec rm -i {} \;

У цьому прикладі я хочу видалити ті файли резервного копіювання, які створює emacs. Однак цей тильд може бути в якомусь незрозумілому файлі, про який я не знаю і може бути важливим. Плюс я хочу підтвердити видалення. Тому я ставлю опцію '-i' команді rm. Це дасть мені інтерактивне видалення.

Також ви можете уточнити використання rm для видалення каталогів, а також файлів:

find /usr/local/share/ -iname "useless" -exec rm -r {} \;

Якщо коротко, -exec дає вам трохи більше контролю над фактичною командою, яка видаляє знайдений елемент. Перевага полягає в тому, що ви використовуєте один інструмент для пошуку файлів, інший інструмент для їх видалення. Також не кожна версія утиліти find має опцію -delete. Тож краще використовувати кожен інструмент для його належної роботи. Це філософія unix - один інструмент, одна робота, використовуйте їх разом, щоб робити те, що вам потрібно зробити.


3
Дивіться також -ok rm {} \;замість -exec rm {} \;інтерактивного підтвердження.
Кусалаланда
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.