Was ist Befehlssubstitution in einer Shell? [duplizieren]

Diese Frage hat hier bereits Antworten :

Kommentare

  • OK, jeder muss sich entspannen und aufhören, sich gegenseitig Trolling vorzuwerfen. Wenn Sie ' eine Frage nicht mögen, stimmen Sie sie ab oder ignorieren Sie sie und gehen Sie weg . Wenn Sie das Gefühl haben, dass Sie ' in Kommentaren angegriffen werden, aktivieren Sie nicht, sondern markieren Sie und gehen Sie weg .
  • Auch verwandt: Was ' ist der Unterschied zwischen $ (stuff) und `stuff`?
  • Anzeigen des Die Ausgabe eines Befehls mit Befehlssubstitution und echo ist ein schlechtes Beispiel für die Befehlssubstitution, da 1) die Ausgabe ohnehin angezeigt worden wäre, 2) printf ist sicherer für variable Daten. Das Beispiel könnte auch geschrieben werden: date | sed 's/^/Today is /'
  • @Kusalananda Ich sehe Ihren Standpunkt darin, es sofort zu drucken (mit printf ) ist nutzlos. Ich habe die Formulierung ein wenig geändert, von sofort zu sometime later. Ist sie ansprechender?
  • Das Beispiel könnte thedate=$(date), gefolgt von printf 'The date is %s\n' "$thedate".

Antwort

" Befehlsersetzung " ist der Name der Funktion der Shell-Sprache, mit der Sie einen Befehl ausführen und die Ausgabe dieses Befehls ersetzen lassen können ( Ersatz) den Text des Befehls.

Es gibt keine andere Funktion der Shell-Sprache, mit der Sie dies tun können.

Eine Befehlsersetzung, dh die gesamte $(...) Ausdruck wird durch seine Ausgabe ersetzt . Dies ist die primäre Verwendung von Befehlssubstitutionen.

Der Befehl, den die Befehlssubstitution ausführt, wird in a ausgeführt Subshell, dh, es verfügt über eine eigene Umgebung, die sich nicht auf die Umgebung der übergeordneten Shell auswirkt.

Nicht alle Subshell-Ausführungen sind Befehlsersetzungen ugh (siehe weitere Beispiele am Ende).

Beispiel, das zeigt, dass eine Befehlssubstitution in einer Subshell ausgeführt wird:

$ s=123 $ echo "hello $( s=world; echo "$s" )" hello world $ echo "$s" 123 

Hier das Die Variable s wird auf die Zeichenfolge 123 gesetzt. In der nächsten Zeile wird echo für eine Zeichenfolge aufgerufen, die das Ergebnis einer Befehlsersetzung enthält. Die Befehlssubstitution setzt s auf die Zeichenfolge world und gibt diese Zeichenfolge wieder. Die Zeichenfolge world ist die Ausgabe des Befehls in der Befehlssubstitution und daher, wenn dies unter set -x würden wir sehen, dass die zweite Zeile oben auf echo "hello world" erweitert worden wäre, was hello world auf dem Terminal erzeugt:

$ set -x $ echo "hello $( s=world; echo "$s" )" ++ s=world ++ echo world + echo "hello world" hello world 

(bash fügt jeder Ebene von eine zusätzliche Ebene von + -Aufforderungen hinzu Eine Befehlssubstitutions-Subshell in der Trace-Ausgabe, andere Shells tun dies möglicherweise nicht.

Zuletzt zeigen wir, dass der Befehl innerhalb der Befehlssubstitution in einer eigenen Subshell ausgeführt wurde, da er den Wert von s in der aufrufenden Shell (der Wert von s ist immer noch 123, nicht world).

Es gibt andere Situationen, in denen Befehle in Unterschalen ausgeführt werden, z. B. in

echo "hello" | read message 

In bash Sofern Sie nicht die Option lastpipe festlegen (nur in nicht interaktiven Instanzen), wird read in einer Subshell ausgeführt dass $message in der übergeordneten Shell nicht geändert wird, dh wenn Sie echo "$message" nach dem obigen Befehl ausführen, wird eine leere Zeichenfolge (oder ein beliebiger Wert $message war vorher).

Eine Prozessersetzung in bash wird auch in einer Unterschale ausgeführt:

cat < <( echo "hello world" ) 

Auch dies unterscheidet sich von einer Befehlsersetzung.

Kommentare

  • Für Bash 4.2, Wenn shopt lastpipe gesetzt ist, die Jobsteuerung nicht aktiv ist und die Pipeline nicht im Hintergrund ist, wird der letzte Befehl nicht in einer Subshell ausgeführt.
  • Sie sagen: „Es gibt keine andere Funktion der Shell-Sprache, mit der Sie dies tun können.“ Auf die Gefahr hin, Haare zu spalten, können Sie cmd₁ > myfile / read -r var < myfile / cmd₂ "$var" ausführen . Bei Bedarf können Sie dies erweitern, um mehrzeilige Daten zu verarbeiten.
  • @ G-Man Ja, und Sie können auch ein neues Shell-Skript in eine Datei schreiben und dieses ausführen.Es gibt jedoch keine andere Funktion, mit der ein Textstück durch die Ausgabe eines Befehls ersetzt werden kann.

Antwort

a=$(command) 

speichert den Ergebniswert von command in der Variablen.

Es steckt wirklich nichts mehr dahinter.

Als Randnotiz glaube ich:

a=`command` 

ist veraltet und hat die Dieselbe Bedeutung wie oben.

Kommentare

  • Ergebnis Hier ist die Standardausgabe des Befehls, der von allen nachfolgenden Zeilenumbrüchen befreit ist Zeichen (und einige Variationen zwischen Shells, wenn die Ausgabe kein Text ist). Beachten Sie, dass `...` die Bourne der csh-Syntax ist, während $(...) die Korn / POSIX-Syntax ist (mit `...` wird aus Gründen der Abwärtskompatibilität weiterhin unterstützt)
  • @St é phaneChazelas Vielen Dank für wertvolle Informationen und Sie können die Antwort so bearbeiten, dass sie diese enthält.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.