Backtick verstehen (`)

35

Ich probiere den Befehl aus

$ b=5; echo `$b`;
-bash: 5: command not found

Aber es wird nicht 5 gedruckt, wie es soll. Was vermisse ich hier?

Was bedeutet `(backquote / backtick) in Befehlen? scheint zu sagen, dass `die Befehle ausgewertet und durch die Ausgabe ersetzt werden.

coolcric
quelle
8
Beachten Sie, dass Backticks nicht empfohlen werden, da Sie sonst keine verschachtelten Ausführungsersetzungen mehr ausführen können. Insetad wird $ (irgendwann) bevorzugt. Imho es verbessert die Lesbarkeit.
Tommy
6
@Tommy, Nein, Backticks können verschachtelt werden, aber es wird zu einem Albtraum, vor allem, wenn auch doppelte Anführungszeichen verwendet werden.
Stéphane Chazelas

Antworten:

52

Text zwischen Backticks wird ausgeführt und durch die Ausgabe des Befehls ersetzt (abzüglich der nachgestellten Zeilenumbrüche, und achten Sie darauf, dass das Shell-Verhalten variiert, wenn die Ausgabe NUL-Zeichen enthält). Dies wird als Befehlsersetzung bezeichnet, da sie durch die Ausgabe des Befehls ersetzt wird. Wenn Sie also 5 drucken möchten, können Sie keine Backticks verwenden, Sie können Anführungszeichen verwenden, wie ein echo "$b"beliebiges Zitat , oder Sie können es einfach löschen und verwenden echo $b.

Wie Sie sehen, $bschlägt bashdie Ausführung des Befehls bei Verwendung von Backticks 5mit der Fehlermeldung fehl, da der Befehl 5 enthält .

Um zu verstehen, wie Backticks funktionieren, versuchen Sie Folgendes:

$ A=`cat /etc/passwd | head -n1`
$ echo "$A"

cat /etc/passwd |head -n1sollte die erste Zeile der /etc/passwdDatei drucken . Da wir jedoch Backticks verwenden, wird dies nicht auf der Konsole gedruckt. Stattdessen wird es in AVariable gespeichert . Das können Sie bestätigen $A. Beachten Sie, dass eine effizientere Methode zum Drucken der ersten Zeile der Befehl ist, head -n1 /etc/passwdaber ich möchte darauf hinweisen, dass der Ausdruck in Backticks nicht einfach sein muss.

Wenn also die erste Zeile von / etc / passwd ist root:x:0:0:root:/root:/bin/bash, wird der erste Befehl dynamisch durch bash to ersetzt A="root:x:0:0:root:/root:/bin/bash".

Beachten Sie, dass diese Syntax der Bourne-Shell entspricht. Zitieren und Entkommen wird schnell zum Albtraum, besonders wenn Sie anfangen, sie zu nisten. Ksh stellte die $(...)Alternative vor, die jetzt standardisiert ist ( POSIX ) und von allen Shells unterstützt wird (sogar die Bourne-Shell von Unix v9). Daher sollten Sie $(...)heutzutage stattdessen verwenden, es sei denn, Sie müssen für sehr alte Bourne-Muscheln tragbar sein.

Beachten Sie auch, dass die Ausgabe von `...`und $(...)der Wortteilung und der Generierung von Dateinamen genau wie die Variablenerweiterung (in zsh nur Wortteilung) unterliegen und daher im Allgemeinen in Listenkontexten angegeben werden müssten.

Krzysztof Adamski
quelle
1
Hallo @Krzysztof, das ist hilfreich! "da $ b 5 enthält, versucht bash, befehl 5 auszuführen" ist genau das, wonach ich gesucht habe
coolcric
you can use quotation marks, like echo "$b"=> macht der "" etwas besonderes? Es scheint, als echo $bwürde es genauso gut funktionieren.
Tootsie Rolls
@Anita: Im Allgemeinen führen Anführungszeichen einige spezielle Aktionen aus (dies ändert die Art und Weise, wie Sonderzeichen behandelt werden - insbesondere Leerzeichen), in diesem Fall können sie jedoch ohne große Probleme gelöscht werden. Dies liegt daran, dass keine Sonderzeichen verwendet werden und der echoBefehl sich nicht um die Anzahl der Argumente kümmert. Wenn er balso Leerzeichen enthält, werden mehrere Argumente abgerufen und trotzdem gedruckt. Dies ist bei anderen Befehlen möglicherweise nicht der Fall (insbesondere, wenn die Variable nicht gesetzt ist), daher tendiere ich dazu, Variablen immer in Anführungszeichen zu setzen.
Krzysztof Adamski
wäre nett wenn (POSIX)ein link zum eigentlichen standard wäre.
Erikbwork
1
@ erikb85: Diese Notiz wurde von mir nicht hinzugefügt, aber ich habe sie mit dem von Ihnen vorgeschlagenen Link bearbeitet :)
Krzysztof Adamski
11

Der Backtick macht genau das, was Sie sagen. Sie haben eine Variable auf eine Ganzzahl gesetzt. Wenn Sie diese Variable in Backticks einfügen, versucht bash, sie als Befehl auszuführen. Da es sich nicht um einen Befehl handelt, erhalten Sie den Fehler, den Sie gesehen haben.

Was Sie tun möchten, ist einfach:

$ b=5; echo $b

Um Backticks besser zu verstehen, vergleichen Sie mit:

$ b=5; a=`echo $b`; echo $a
  5
terdon
quelle
8

Wenn Sie Schritt für Schritt vorgehen, sollte dies in Ihrer Zeile erklärt werden.

$ b=5; echo `$b`;
  1. Setzt die Variable bauf 5
  2. wertet aus $b(läuft effektiv 5)
  3. echoDies ist die Ausgabe der obigen Auswertung.

Also ja, die Ausgabe, die Sie erhalten haben, wird erwartet. Sie bewerten den Inhalt einer Variablen und nicht den tatsächlichen Befehl, von dem Sie dachten, er sei. Alles, was Sie in Backticks einfügen, wird simplay in einer neuen (Sub-) Shell ausgewertet (ausgeführt).

gertvdijk
quelle
hi @gertvdijk, danke für deinen Beitrag! Ich habe gedacht, dass `das zurückgibt, was auch immer übrig bleibt, nachdem der Inhalt ausgewertet wurde. Also dachte ich, "$ b" hätte 5 zurückgegeben, damit Echo es druckt
coolcric