Vor kurzem habe ich den Befehl echo verwendet, dem $ vorangestellt ist. Zu meiner Überraschung war das Ergebnis ein Fehler. Mein Befehl war ungefähr so.

# !/bin/bash $(echo "a") 

Der Fehler war ..

./test1.sh: line 3: a: command not found 

Kann mir jemand erklären, was hier passiert. Vielen Dank im Voraus.

Antwort

$(echo a) ist eine „Befehlsersetzung“. Die $(...) wird durch die Ausgabe des Befehls in ersetzt. Die Ausgabe in diesem Fall ist a, die die Shell dann auszuführen versucht. Die Shell kann den Befehl a nicht finden und Sie erhalten die Fehlermeldung.

Es ist unklar, was Sie damit beabsichtigt haben oder was Sie erwartet haben Es ist sehr ungewöhnlich, dass das Ergebnis einer Befehlssubstitution ausgeführt werden soll.


Einige Programme geben Zeichenfolgen aus, die von der Shell ausgewertet werden sollen Siehe Code wie

eval "$(ssh-agent)" 

, der die Ausgabe des angegebenen Befehls auswertet (ausführt). Diese Befehle haben eine streng spezifizierte Ausgabe und werden im Allgemeinen als sicher ausgeführt Im obigen Beispiel startet ssh-agent den SSH-Agentenprozess und gibt einige Befehle aus, mit denen die entsprechenden Umgebungsvariablen festgelegt werden, die ssh Der Client muss später den Agenten verwenden, z. B.

SSH_AUTH_SOCK=/tmp/ssh-Ppg1EO5eRIZp/agent.6017; export SSH_AUTH_SOCK; SSH_AGENT_PID=6018; export SSH_AGENT_PID; echo Agent pid 6018; 

Dies wird dann von eval ausgewertet.

eval wird hier und nicht nur verwendet Verwenden Sie einfach $(ssh-agent), da die Ausgabe des Befehls ssh-agent eher ein zusammengesetzter Befehl ist. Ohne eval wären die Befehlsabschlusszeichen ; netto etwas Besonderes.

Beispiel:

$ s="echo hello; echo world" $ $s hello; echo world $ eval "$s" hello world 

Kommentare

  • OTOH, eval "$(dircolors)" ist eine vernünftige Sache. Gleiches gilt für mehrere andere Befehle, die diesem Muster folgen, z. B. gpg-agent.
  • @derobert Yes und $(ssh-agent). Guter Punkt.

Antwort

Sie können set -x verwenden Sehen Sie, was die Shell tut:

set -x $(echo "a") ++ echo a + a 

Die Shell führt echo a aus und setzt die Ausgabe in die Befehlszeile. Dies ist das gleiche, als hätten Sie versucht, diese Befehlszeile auszuführen:

a 

Die Shell sucht nach einem Befehl a im Pfad (und sogar zuvor in der Funktions-, Alias- und Hash-Liste) findet es nicht und löst daher einen Fehler aus.

Es funktioniert, wenn die Ausgabe ein gültiger Befehl ist:

$(echo "ls") 

Kommentare

  • können Sie mir sagen, wofür wir tatsächlich $ other verwenden, als eine Variable aufzurufen.
  • @Ashu Es wird offensichtlich auch zur Befehlsersetzung verwendet – Ihr Fall. Außerdem erscheint es in der Berechnung (echo $((1+2+3))), der Zeichenfolgenerstellung ($'foo\nbar' / $"foo") und (weniger Shell-bezogen) in den regulären Ausdrücken, die bash versteht ([[ foo =~ ^f..$ ]]). Es wird auch zum Ändern von Variablen auf verschiedene Arten verwendet: ${foo#bar}

Schreibe einen Kommentar

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