Was bedeutet es in der Shell, wenn wir einen Befehl in Dollarzeichen und Klammern setzen: $ (Befehl)

109

Ich möchte nur die folgende Codezeile in der Shell verstehen. Es wird verwendet, um das aktuelle Arbeitsverzeichnis abzurufen. Mir ist bekannt, dass $(variable)name den Wert innerhalb des Variablennamens zurückgibt, aber was $(command)soll zurückgeben? Gibt es den Wert zurück, nachdem der Befehl ausgeführt wurde? In diesem Fall können wir `den Befehl ausführen.

CWD="$(cd "$(dirname $0)"; pwd)"

Dieselbe Ausgabe kann aus der folgenden Codezeile auch in verschiedenen Versionen der Shell übernommen werden

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Ich kann die Bedeutung von $(cd..und nicht verstehen $(dirname.

Könnte mir jemand helfen, herauszufinden, wie dieser Befehl ausgeführt wird?

KItis
quelle
1
Und hier ist eine Frage zu den Vor- und Nachteilen von $()vs ``.: stackoverflow.com/questions/9449778/…
Keine

Antworten:

114

Die Verwendung von $Ähnlichem ${HOME}ergibt den Wert von HOME. Die Verwendung der $gleichen $(echo foo)Mittel bedeutet, dass alles, was sich in den Klammern befindet, in einer Unterschale ausgeführt und als Wert zurückgegeben wird. In meinem Beispiel würden Sie bekommen, fooda echowird foonach Standard ausschreiben

Eric Urban
quelle
37
Ja; $(...)ist eine bessere Möglichkeit, einen Befehl zu schreiben, als zu versuchen, Anführungszeichen zu verwenden. Denken Sie darüber nach, zu schreiben: gcclib=$(dirname $(dirname $(which gcc)))/libVerwenden Sie Anführungszeichen. Noch bevor Sie in Markdown in die Schwierigkeiten geraten, ist es schwieriger, sich den Anführungszeichen der verschachtelten Befehle zu entziehen, während Sie dies nicht mit der $(...)Notation tun .
Jonathan Leffler
7
Technisch $(echo foo)wird eine Befehlsersetzung erstellt, keine Unterschale. Die andere aktuelle Antwort macht das richtig. Ich denke, die Befehlssubstitution wird in einer Art Subshell ausgeführt, aber es handelt sich immer noch um unterschiedliche Konzepte.
Tryse
4
@trysis - Befehlssubstitution wird definitiv in einer Subshell ausgeführt , und es lohnt sich, darauf hinzuweisen .
Eliran Malka
2
Ich verstehe, dass die Backticks das gleiche Ergebnis wie $ () liefern, aber ist der Unterschied rein kosmetisch? Gibt es einen Grund, eins gegen das andere zu verwenden, abgesehen davon, dass $ () besser lesbar ist?
Mitchell Tracy
2
"Die Verwendung von $ like $ (echo foo) bedeutet, dass alles, was in den Klammern steht, in einer Unterschale ausgeführt und als Wert zurückgegeben wird." ... Dies ist verwirrend, da dieser Befehl $(echo foo)versucht, das auszuführen, was aus den Klammern zurückgegeben wird. Er wird zuerst ausgeführt und echo foodann ausgeführt foo, was einen Fehler darstellt
Buchhalter م
21
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Könnte mir jemand helfen, herauszufinden, wie dieser Befehl ausgeführt wird?

Schauen wir uns verschiedene Teile des Befehls an. BASH_SOURCEist eine Bash-Array-Variable, die Quelldateinamen enthält. Also "${BASH_SOURCE[0]}"würden Sie den Namen der Skriptdatei zurückgeben.

dirnameist ein Dienstprogramm von GNU coreutils, das die letzte Komponente aus dem Dateinamen entfernt. Wenn Sie also Ihr Skript ausführen, indem Sie sagen bash foo, "$( dirname "${BASH_SOURCE[0]}" )"würde zurückkehren .. Wenn Sie sagten bash ../foo, würde es zurückkehren ..; denn bash /some/path/fooes würde zurückkehren /some/path.

Schließlich "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"erhält der gesamte Befehl das absolute Verzeichnis, das das aufgerufene Skript enthält.

$(...) Ermöglicht die Ersetzung von Befehlen, dh die Ausgabe eines Befehls ersetzt den Befehl selbst und kann verschachtelt werden.

devnull
quelle
1
Tut mir leid, dass ich 3 Jahre zu spät zur Party gekommen bin, aber kannst du bitte erklären, warum die Aussage funktioniert? Sie sagten, dirnamegibt den Pfad der ausgeführten Datei zurück (relativ oder absolut zum aktuellen Arbeitsverzeichnis), cdändert das pwd in dieses Verzeichnis und pwddruckt den absoluten Pfad des aktuellen Arbeitsverzeichnisses aus. Aber warum kommen sie dazu &&? Und was DIRhält, wenn das cdfehlschlägt?
Christian
2
@Christian &&verhindert , dass das pwdausgeführt wird, wenn das cdfehlschlägt, sodass DIRes leer ist und kein falsches Verzeichnis hat.
Charles Duffy