Wie funktioniert dieser Suchbefehl mit "find … -exec sh -c '…' sh {} +"?

Wie funktioniert dieser Suchbefehl mit "find … -exec sh -c '…' sh {} +"?

@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 -execden 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 {} +

findfindet eine Anzahl von Dateien basierend auf den Kriterien ...und wird cmdmit 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 cmdmehrmals 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 +

cmdWenn 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 cfür das inline-script, $0ist x, $1ist ... also ist die Liste dieser 3 Argumente: a, b und c. Also ain $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-shund "$@"ist die Liste der Dateien (zu der es finderweitert wird {}).

Durch Verwendung des execspeziellen 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 zshund einige Implementierungen von kshtun dies implizit für den letzten Befehl in einem Inline-Skript (auch bashwenn das Inline-Skript nur einen Befehl enthält, wie hier).

verwandte Informationen