- „Oczywiście”
-exec …
musi być zakończone średnikiem ( ;
) lub znakiem plus ( +
). Średnik jest szczególną postacią w skorupkach (lub, co najmniej, każdy Shell jaki kiedykolwiek używane), więc, jeśli ma być używany jako część find
polecenia , należy uciec lub cytowany ( \;
, ";"
lub ';'
).
Za -exec … ;
pomocą {}
ciąg może pojawić się dowolną liczbę razy w poleceniu, w tym zero lub dwa lub więcej w dowolnej pozycji.
Zobacz to
na przykład, dlaczego możesz chcieć to zrobić -exec
bez użycia {}
.
Posiadanie dwóch lub więcej występów jest przydatna przede wszystkim dlatego, że w (co najmniej) niektóre wersje find
The {}
nie musi być słowo samo w sobie; może mieć inne postacie na początku lub na końcu; na przykład,
find . -type f -exec mv {} {}.bak ";"
Za pomocą -exec … +
, {}
ciąg musi pojawić się jako ostatni argument przed +
. Polecenie jak
find . -name "*.bak" -exec mv {} backup_folder +
powoduje enigmatyczny find: missing argument to ‘-exec’
komunikat o błędzie.
Obejściem tego, które jest specyficzne dla poleceń cp
i mv
, jest
find . -name "*.bak" -exec mv -t backup_folder {} +
lub
find . -name "*.bak" -exec mv --target-directory=backup_folder {} +
{}
Musi być słowo samo w sobie; nie może mieć innych znaków na początku ani na końcu. I w (przynajmniej) niektórych wersjach find
możesz nie mieć więcej niż jedną {}
.
Uwaga o zdrowiu psychicznym: Możesz powiedzieć
odnaleźć . -name "* .sh" -type f -executable -exec {} opcjonalne argumenty tutaj ";"
aby uruchomić każdy ze skryptów. Ale
odnaleźć . -nazwa „* .sh” -type f -executable -exec {} +
uruchamia jeden ze skryptów z nazwami wszystkich pozostałych jako parametrami. To jest podobne do powiedzenia
./*.sh
jako polecenie powłoki, z wyjątkiem tego, find
że nie gwarantuje, że posortuje wyniki, więc nie masz gwarancji, że uruchomisz aaa.sh
(twój alfabetycznie pierwszy *.sh
plik) tak jak w przypadku uruchamiania ./*.sh
.
Aspektem find
tego może nie być całkowicie jasne dla początkujących jest to, że wiersz poleceń jest w rzeczywistości wykonywalną instrukcją w tajemnym języku. Na przykład,
find . -name "*.sh" -type f -executable -print
znaczy
for each file
if the file’s name matches `*.sh` (i.e., if it ends with `.sh`)
then
if it is a plain file (i.e., not a directory)
then
if it is executable (i.e., the appropriate `---x--x--x` bit is set)
then
print the file’s name
end if
end if
end if
end loop
lub po prostu,
for each file
if the file’s name matches `*.sh` AND it is a plain file AND it is executable
then
print the file’s name
end if
end loop
Niektóre -
słowa kluczowe są zarówno działaniem wykonywalnym, jak i testem. W szczególności dotyczy to -exec … ;
; na przykład,
find . -type f -exec grep -q cat {} ";" -print
przetłumaczyć na
dla każdego pliku
jeśli jest to zwykły plik (tzn. nie katalog)
następnie
wykonaj grep -q nazwa pliku kota
jeśli proces się powiedzie (tzn. zakończy się ze statusem 0)
następnie
wydrukuj nazwę pliku
koniec jeśli
koniec jeśli
pętla końcowa
który wypisze nazwy wszystkich plików zawierających ciąg „ cat
”. I chociaż jest to coś, co grep
można zrobić samodzielnie (z opcją -l
(małe litery L
)), przydatne może być użycie go find
do znalezienia plików zawierających określony ciąg ORAZ o określonym rozmiarze ORAZ należących do określonego właściciela AND zostały zmodyfikowane w określonym przedziale czasowym….
To jednak nie działa -exec … +
. Ponieważ -exec … +
wykonuje jedno polecenie dla wielu plików, nie ma sensu używać go jako warunku logicznego w for each file …
pętli.
- Drugą stroną powyższego jest to, że
find
zazwyczaj kończy pracę ze statusem wyjścia 0, chyba że podasz nieprawidłowe argumenty lub napotka katalog, którego nie może odczytać. Nawet jeśli program, który wykonasz nie powiedzie się (zakończy działanie z niezerowym statusem wyjścia),
find
zakończy działanie ze statusem wyjścia równym 0.
Z wyjątkiem sytuacji, gdy program, który wykonujesz z -exec … +
błędem (zakończy działanie z niezerowym statusem wyjścia),
find
zakończy działanie z niezerowym statusem wyjścia.
... -exec mv {} {}.bak ...
nie gwarantuje poprawnego działania we wszystkichfind
implementacjach. Standardowe stany POSIX{}
muszą pojawiać się same, aby zawsze były rozpoznawane, w przeciwnym razie zachowanie może pozostawić znaki bez zmian lub zastąpić je nazwą ścieżki. W pierwszym przypadku całe polecenie spowoduje usunięcie wszystkich plików, ale ostatni z nich zostanie znaleziony ...