Jaki jest brakujący argument dla -exec?

15

Używam następującego polecenia, aby wyczyścić katalog, pliki i katalogi powyżej 30 dni, i przenieść je do katalogu archiwum, który mogę usunąć po kilku tygodniach, jeśli nikt nie poprosi o ich odzyskanie. Katalog docelowy ma podkatalogi według nazwy użytkownika, podobnie jak katalog archiwum.

Oto polecenie, którego używam:

find /path/to/directory/username/ -mtime +30 -exec mv "{}" /path/to/archive/username/ \;

Zasugerowałem zmodyfikowaną wersję tego, aby odpowiedzieć na pytanie zadać ubuntu inny użytkownik edytować kod, aby zmienić końca linii \;dla +jak to szybciej (i bardziej poprawne?). Spójrz tutaj

Jednak użycie +w ten sposób działa, jeśli -execpolecenie ls -lhnie zawiera rzeczywistego polecenia, którego używam. Jeśli spróbuję, pojawi +się komunikat o błędzie:

find: missing argument to '-exec'

Nie rozumiem, dlaczego tak się zachowuje ani jakie byłoby prawidłowe polecenie. Proszę nie pisać tylko korekty polecenia, chciałbym raczej zrozumieć niż ślepo stosować się do sugestii.

Arroniczny
źródło
Czy odnosisz się do tej odpowiedzi ? To może wyjaśniać, dlaczego
Wilf
Dzięki @Wilf Zaktualizowałem, aby pokazać, na którą odpowiedź nastąpiła edycja. Link, który podałeś, zawiera kolejny link, który wyjaśnia to w sposób, z którym mój mózg może sobie poradzić.
Arronical
Dzięki @souravc w genialnie cykliczny sposób to pytanie zadaje użytkownik, który edytował moje polecenie! Wreszcie dostaję, że +dostarcza wielu argumentów do tego samego polecenia, ale mvnie mogę sobie z tym poradzić!
Arroniczny
@Arronical mv can, patrz moja odpowiedź ^^
chaos

Odpowiedzi:

19

Użytkownik w tym poście może powiedzieć, że +znak na końcu -execpolecenia jest szybszy, ale nie dlaczego.

Załóżmy, że findpolecenie zwróci następujące pliki:

/path/to/file1
/path/to/file2
/path/to/file3

Normalne -execpolecenie ( -exec command {} \;) jest uruchamiane raz dla każdego pasującego pliku. Na przykład:

find ... -exec mv {} /target/ \;

Wykonuje:

mv /path/to/file1 /target/
mv /path/to/file2 /target/
mv /path/to/file3 /target/

Jeśli używasz +znaku ( -exec command {} +), komenda jest budowana przez dodanie wielu dopasowanych plików na końcu polecenia. Na przykład:

find ... -exec mv -t /target/ {} +

Wykonuje:

mv -t /target/ /path/to/file1 /path/to/file2 /path/to/file3

Aby +poprawnie użyć flagi, argument do przetworzenia musi znajdować się na końcu polecenia, a nie w środku. Dlatego w twoim przykładzie findtrows missing argument to '-exec'; tęskni za zamknięciem {}.

chaos
źródło
Zawsze zastanawiałem się, dlaczego find -execwymaga, {}aby był to ostatni argument, gdy jest używany z +. Czy ktoś wie, dlaczego podjęto tę decyzję projektową, zamiast pozwolić konstrukcjom takim jak wiersz poleceń OP?
Peter Cordes,
11

Użytkownik wyjaśnił ich edycję ...

Terminator „+” exec jest szybszy niż „\;”  patrz /ubuntu/558817/what-is-the-difference-between-using-and-in-exec-command;  i utworzenie pliku kopii zapasowej z oryginalnego pliku jest dobrym pomysłem

... używając tego linku . Myślę, że w zasadzie zamiast używać wielu poleceń, wysyła wszystkie nazwy plików do jednej instancji polecenia, aby przyspieszyć. Oto przykład z tego miejsca :

Użycie -exec z średnikiem ( find . -exec ls '{}' \;) spowoduje wykonanie

ls file1
ls file2
ls file3

Ale jeśli zamiast tego użyjesz znaku plus ( find . -exec ls '{}' \+), wszystkie nazwy plików zostaną przekazane jako argumenty do pojedynczego polecenia:

ls file1 file2 file3

Istnieją inne formularze dostępne za pomocą ;i +również ( stąd :)

Dlatego dozwolona jest następująca przykładowa składnia polecenia find:

find . -exec echo {} \;
find . -exec echo {} ';'
find . -exec echo {} ";"
find . -exec echo {} \+
find . -exec echo {} +

JEDNAK nie jestem pewien, czy to i tak będzie działać z poleceniem move, ponieważ jest to składnia mv [OPTION]... SOURCE DEST, chyba że -tużyto opcji lub podobnego. Powinien jednak działać bez lsżadnych dodatkowych opcji itp., Ponieważ mogą zrozumieć, gdy podano wiele nazw plików. +Mogą również muszą być uciekł (tj \+)

Wilf
źródło
Obie świetne odpowiedzi, ale muszę dać temu chaos za to, że jestem trochę szybszy i wyjaśniam mv -toba + 1!
Arroniczny