@StephaneChazelas hat die folgende Lösung für dieses Q&A gepostet:Ich habe einige Probleme bei der Verwendung von „find -exec {} +“.
$ find . -iname "*.extension" -exec sh -c '
exec <command> "$@" <additional parameters>' sh {} +
Was genau ist hier los? Was genau macht das letzte sh {}
? Es scheint, als wäre es nur da, um -exec
den Befehl von find zu beruhigen, damit er etwas zu tun hat, ein NOOP.
Ich könnte es genauso gut echo {}
dort einfügen und es scheint einwandfrei zu funktionieren.
Antwort1
Die Syntax lautet:
find ... -exec cmd {} +
find
findet eine Anzahl von Dateien basierend auf den Kriterien ...
und wird cmd
mit dieser Liste von Dateipfaden als Argumenten ausgeführt, so viele wie möglich, ohne die Beschränkung der Größe der Argumente eines Befehls zu überschreiten.
Bei Bedarf kann die Dateiliste aufgeteilt und cmd
mehrmals aufgerufen werden. Beispielsweise kann es am Ende folgendermaßen aussehen:
cmd ./file1 ./file2 ... ./file3000
cmd ./file3001 ./file3002 ... ./file4321
Eine Einschränkung dabei ist, dass dies {}
zuletzt sein muss. Sie können beispielsweise nicht schreiben:
find ... -exec cmd {} other args +
wie Sie es mit ';'
anstelle von könnten '+'
.
Du kannst schreiben:
find ... -exec echo foo {} +
aber nicht:
find ... -exec echo {} foo +
cmd
Wenn Sie also nach der Dateiliste zusätzliche Argumente hinzufügen müssen , müssen Sie eine Shell aufrufen. (Andere Gründe, warum Sie eine Shell aufrufen müssen, sind immer dann, wenn Sie eine Shell-Funktion wie Umleitungen, Pipes, einige Zeichenfolgenerweiterungen usw. verwenden müssen.)
In ist sh -c 'inline-script' x a b c
für das inline-script
, $0
ist x
, $1
ist ... also ist die Liste dieser 3 Argumente: a, b und c. Also a
in $2
:b
"$@"
find ... -exec sh -c 'cmd "$@" other arg' find-sh {} +
Für dieInline-Skript, $0
(das beispielsweise zum Anzeigen von Fehlermeldungen verwendet wird) ist auf eingestellt find-sh
und "$@"
ist die Liste der Dateien (zu der es find
erweitert wird {}
).
Durch Verwendung des exec
speziellen Built-In der Shell:
find ... -exec sh -c 'exec cmd "$@" other arg' find-sh {} +
Wir sagen der Shell, dass sie keinen zusätzlichen Prozess zum Ausführen von aufspalten soll cmd
, sondern ihn im selben Prozess ausführen soll (wobei der laufende Shell-Prozess durch diesen Befehl ersetzt wird). Einige Shells wie zsh
und einige Implementierungen von ksh
tun dies implizit für den letzten Befehl in einem Inline-Skript (auch bash
wenn das Inline-Skript nur einen Befehl enthält, wie hier).