Verwendung von eingeschlossenen geschweiften Klammern {} als Argumente für Befehle und deren Optionen

11

Beispiele

Ich habe kürzlich Beispiele für die Verwendung von Paaren umschließender Klammern gefunden {}, wobei zwischen den öffnenden und schließenden Klammern nichts als Argumente für Befehle und sogar für deren Optionen steht:

cat foo | xargs -I{} echo {}

find . -size 0 -exec rm -i {} \;

Keine Dokumentation

Mein Problem ist, dass ich im GNU Bash Manual keine Dokumentation finden kann , die die Verwendung {}in einem solchen Kontext wie in den obigen Beispielen beschreibt.

Ich denke nicht, dass es sich um eine Parametererweiterung handelt , da bei einer Parametererweiterung wie in ein Dollarzeichen vor den einschließenden Klammern stehen muss ${}.

Es kann auch keine Klammererweiterung sein, da sie die Form hat {x..y[..incr]}, wo xund ynicht optional ist.

Es kann auch keine Befehlsgruppierung sein, da {}sie als Argumente verwendet wird.

Fragen

  1. Was bedeutet ein Paar umschließender Klammern {}im Allgemeinen überhaupt als Argument für einen Befehl, der es akzeptiert?

  2. Wo finde ich eine Dokumentation, die die Verwendung {}als Argumente beschreibt?

Niko Gambt
quelle
Einige Befehle verfügen über diese Optionen. Dies {}bedeutet targets, dass mit dem findBefehl rmDateien entfernt / gefunden werden.
Tuyen Pham

Antworten:

16

Diese geschweiften Klammern werden durch Bash allein gelassen; sie gehören findund xargssind und werden in ihren Mann-Seiten beschrieben.

man find

-exec Befehl ;

Befehl ausführen ; true, wenn der Status 0 zurückgegeben wird. Alle folgenden zu suchenden Argumente gelten als Argumente für den Befehl, bis ein bestehendes Argument gefunden ;wird. Die Zeichenfolge {}wird durch den aktuellen Dateinamen ersetzt, der überall dort verarbeitet wird, wo er in den Argumenten des Befehls vorkommt, nicht nur in Argumenten, in denen er allein ist, wie in einigen Versionen von find. Diese beiden Konstruktionen müssen möglicherweise maskiert (mit a \) oder in Anführungszeichen gesetzt werden, um sie vor der Expansion durch die Shell zu schützen. Im Abschnitt BEISPIELE finden Sie Beispiele für die Verwendung der -execOption. Der angegebene Befehlwird einmal für jede übereinstimmende Datei ausgeführt. Der Befehl wird im Startverzeichnis ausgeführt. Es gibt unvermeidbare Sicherheitsprobleme bei der Verwendung der -exec Aktion. Sie sollten -execdirstattdessen die Option verwenden.

-exec Befehl {} +

Diese Variante der -execAktion führt den angegebenen Befehl für die ausgewählten Dateien aus. Die Befehlszeile wird jedoch erstellt, indem jeder ausgewählte Dateiname am Ende angehängt wird. Die Gesamtzahl der Aufrufe des Befehls ist viel geringer als die Anzahl der übereinstimmenden Dateien. Die Befehlszeile wird ähnlich wie die xargsBefehlszeilen erstellt. {}Innerhalb des Befehls ist nur eine Instanz von zulässig. Der Befehl wird im Startverzeichnis ausgeführt. Wenn findein Fehler auftritt, kann dies manchmal zu einem sofortigen Beenden führen, sodass einige ausstehende Befehle möglicherweise überhaupt nicht ausgeführt werden. Diese Variante von gibt -execimmer true zurück.

-execdir Befehl ;

-execdir Befehl {} +

Wie -exec, aber der angegebene Befehl wird aus dem Unterverzeichnis ausgeführt, das die übereinstimmende Datei enthält. Dies ist normalerweise nicht das Verzeichnis, in dem Sie mit der Suche begonnen haben. Dies ist eine viel sicherere Methode zum Aufrufen von Befehlen, da bei der Auflösung der Pfade zu den übereinstimmenden Dateien Race-Bedingungen vermieden werden. Wie bei der -exec Aktion erstellt die + Form von -execdir eine Befehlszeile, um mehr als eine übereinstimmende Datei zu verarbeiten. Bei jedem Befehlsaufruf werden jedoch nur Dateien aufgelistet, die im selben Unterverzeichnis vorhanden sind. Wenn Sie diese Option verwenden, müssen Sie sicherstellen, dass Ihre $PATHUmgebungsvariable nicht referenziert.;; Andernfalls kann ein Angreifer beliebige Befehle ausführen, indem er eine Datei mit dem entsprechenden Namen in einem Verzeichnis belässt, in dem Sie ausgeführt werden -execdir. Gleiches gilt für Einträge, $PATHdie leer oder keine absoluten Verzeichnisnamen sind. Wenn findein Fehler auftritt, kann dies manchmal zu einem sofortigen Beenden führen, sodass einige ausstehende Befehle möglicherweise überhaupt nicht ausgeführt werden. Das Ergebnis der Aktion hängt davon ab, ob die +oder die ;Variante verwendet wird. -execdir Der Befehl gibt {} + immer true zurück, während der -execdir Befehl {} ; nur dann true zurückgibt, wenn der Befehl 0 zurückgibt.

man xargs

-I ersetzen-str

Ersetzen Sie das Auftreten von replace-str in den Anfangsargumenten durch Namen, die aus der Standardeingabe gelesen wurden. Nicht zitierte Leerzeichen beenden auch keine Eingabeelemente. Stattdessen ist das Trennzeichen das Zeilenumbruchzeichen. Impliziert -xund -L 1.

-i[ replace-str ], --replace[ =replace-str ]

Diese Option ist ein Synonym für -Ireplace-str, wenn replace-str angegeben ist. Wenn das Argument replace-str fehlt, ist der Effekt der gleiche wie -I{}. Diese Option ist veraltet. Verwenden Sie -Istattdessen.

Edit: und hier, warum Bash diese geschweiften Klammern ignoriert:

man bash

{ aufführen; }

list wird einfach in der aktuellen Shell-Umgebung ausgeführt. Die Liste muss mit einem Zeilenumbruch oder einem Semikolon abgeschlossen werden. Dies wird als Gruppenbefehl bezeichnet. Der Rückgabestatus ist der Beendigungsstatus der Liste. Beachten Sie, dass im Gegensatz zu den Metazeichen ( und ) , { und } reservierte Worte und muß dort auftreten , wo ein reserviertes Wort erkannt werden darf. Da sie keinen Wortumbruch verursachen, müssen sie durch Leerzeichen oder ein anderes Shell-Metazeichen von der Liste getrennt werden.

Zur Hervorhebung: Die Liste muss mit einem Zeilenumbruch oder einem Semikolon abgeschlossen werden .

basteln
quelle
1
Vielen Dank! Ich ärgere mich, dass derjenige, der schrieb, man xargssich nicht einmal die Mühe gemacht hat zu erklären, was {}eigentlich bedeutet, und der Autor den Leser nicht auf die Erklärung -execin der Manpage von umgeleitet hat (kein Wortspiel beabsichtigt) find.
Niko Gambt
@NikoGambt - Ich sympathisiere ...
Tink
5
@NikoGambt Nun, {} bedeutet für xargs eigentlich nichts, außer dass es der Standardwert für -i ist, der veraltet ist. Ich bin mir nicht sicher, welche Erklärung darüber hinaus notwendig ist. In dem von Ihnen geposteten Beispiel könnte es genauso gut gewesen sein xargs -Iab echo ab; Es ist eine rein willkürliche Wahl.
Random832
@ Random832 Nachdem ich einige weitere Tests mit durchgeführt habe -I, verstehe ich jetzt, was diese Option tatsächlich bewirkt. Ja, {}ist willkürlich, wie Sie sagten. Die Erklärung hat mich nur verwirrt If the replace-str argument is missing, the effect is the same as -I{}. Wenn -Iohne Argument dasselbe wäre wie -I{}, cat foo | xargs -I echo {}würde das gleiche Ergebnis wie beim Ausführen erzielt cat foo | xargs -I{} echo {}. Sie sind jedoch nicht gleich. Ersteres ist ein Fehler, und was mich noch mehr verwirrte, war die Fehlermeldung xargs: {}: No such file or directory, aber das liegt nur an der Implementierung.
Niko Gambt
1
@NikoGambt -I(Großbuchstabe I) kann nicht ohne Argument ausgeführt werden. Das Argument -Iwar echo. Dies ist der Hauptunterschied zwischen -Iund -i(und der Grund, warum -i veraltet ist, da Optionen mit nicht erforderlichen Argumenten ungewöhnlich und verwirrend sind)
Random832