znajdź - exec rm vs -delete

260

Próbuję zrozumieć różnicę między tymi dwoma poleceniami:

sudo find / -name .DS_Store -delete

i

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

Zauważyłem, że execmetoda jest preferowana. Dlaczego? Który jest bezpieczniejszy / szybszy / lepszy? Użyłem obu na moim Macbooku i wszystko wydaje się działać dobrze.

Cebula
źródło

Odpowiedzi:

245

-delete będzie działać lepiej, ponieważ nie musi odradzać zewnętrznego procesu dla każdego dopasowanego pliku.

Możliwe, że zobaczysz -exec rm {} \;często zalecane, ponieważ -deletenie istnieje we wszystkich wersjach find. Nie mogę teraz sprawdzić, ale jestem pewien, że użyłem findgo bez niego.

Obie metody powinny być „bezpieczne”.

EDYCJA na komentarz z @doitmyway: upewnij się, że pasujesz do nazwy, a następnie usuń, a nie odwrotnie (usuń, a następnie dopasuj). W przeciwnym razie każdy plik zostanie usunięty, bez względu na to, czy pasuje . Czyli NIE to zrobić: find / -delete -name .DS_Store.

Typową metodą unikania narzutów związanych z odradzaniem procesu zewnętrznego dla każdego dopasowanego pliku jest:

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

(ale pamiętaj, że tutaj również występuje problem z przenośnością: nie wszystkie wersje find mają -print0!)

Celada
źródło
2
Widzę. Przeczytałem również, że użycie -deleteprzełącznika przed -nameusunięciem określonego drzewa plików, więc myślę, że muszę być ostrożny.
Cebula
8
W ostatnim przypadku findmożesz użyć -exec rm {} +do usunięcia wszystkich pasujących plików za pomocą jednego rmpolecenia.
jimmij
3
.DS_Storenie zawiera żadnych znaków specjalnych, więc cytaty są niepotrzebne i w tym przypadku nic nie zmieniają.
Celada
1
Zasadniczo tylko białe spacje (spacje, tabulatory, może inne) to jedyna rzecz, która powoduje, że niecytowany ciąg znaków jest interpretowany jako dwa osobne argumenty wiersza poleceń, ale to nie wszystko, o co musisz przepraszać, podejmując decyzję o cytowaniu. Musisz się martwić o wszystkie metaznaki powłoki, takie jak ;lub |lub >i <i `` oraz wiele innych, które mają specjalne znaczenie dla powłoki, chyba że są cytowane.
Celada
1
@MarcoMarsala xargszajmuje się problemem listy argumentów o ograniczonym rozmiarze, dzieląc ją na wiele wywołań polecenia.
Celada,
27

Zakładając, że .DS_Storereprezentują pliki, a nie katalogi, najbardziej przenośnym, wciąż najszybszym sposobem na to byłoby:

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

Jedynym ryzykiem jest to, że sudonie będzie dostępne, ale obecnie jest dość niskie.

-deleteOpcja używana do żądania GNU znaleźć i wciąż niestandardowe w wielu innych findimplementacjach, więc nie zawsze jest dostępny.

Zakończenie polecenia +zamiast \;wysoce optymalizuje execklauzulę, nie uruchamiając rmpolecenia dla każdego .DS_Storeelementu obecnego w systemie plików.

jlliagre
źródło
16

W przypadku komputera, takiego jak Macbook, nie znajdziesz dużej różnicy w wydajności między tymi dwoma poleceniami. Jeśli jednak spojrzysz na wersję -exec, zobaczysz subtelną różnicę:

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

Oznacza to, że znajdziesz wszystkie te pliki o nazwie „.file-to-delete”. Jednak to wyszukiwanie może zwrócić niektóre niechciane fałszywe alarmy. Robiąc coś z sudo, powinieneś być bardziej ostrożny. Zaletą użycia -exec rm {} jest to, że możesz przekazywać argumenty do rm w następujący sposób:

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

W tym przykładzie chcę usunąć te pliki kopii zapasowej, które tworzy emacs. Jednak ta tylda może znajdować się w jakimś niejasnym pliku, o którym nie wiem i może być ważna. Plus Chcę potwierdzić usunięcie. Więc umieściłem opcję „-i” w poleceniu rm. To da mi interaktywne usunięcie.

Możesz także sprecyzować użycie rm do usuwania katalogów i plików:

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

W skrócie, -exec daje ci nieco większą kontrolę nad faktycznym poleceniem, które usuwa znaleziony element. Zaletą jest to, że używasz jednego narzędzia do wyszukiwania plików, innego narzędzia do ich usuwania. Również nie każda wersja narzędzia find ma opcję -delete. Lepiej więc użyć każdego narzędzia do poprawnej pracy. Jest to filozofia unixowa - jedno narzędzie, jedno zadanie, używaj ich razem, aby robić to, co musisz zrobić.

Ks. John Jenkins
źródło
3
Zobacz także -ok rm {} \;zamiast -exec rm {} \;interaktywnego potwierdzenia.
Kusalananda