GNU/Linux >> LINUX-Kenntnisse >  >> Linux

eval-Befehl in Bash und seine typischen Verwendungen

eval nimmt eine Zeichenfolge als Argument und wertet sie aus, als ob Sie diese Zeichenfolge in eine Befehlszeile eingegeben hätten. (Wenn Sie mehrere Argumente übergeben, werden diese zunächst mit Leerzeichen verbunden.)

${$n} ist ein Syntaxfehler in bash. Innerhalb der geschweiften Klammern können Sie nur einen Variablennamen mit einigen möglichen Präfixen und Suffixen haben, aber Sie können keine willkürliche Bash-Syntax haben und insbesondere können Sie keine Variablenerweiterung verwenden. Es gibt jedoch eine Art zu sagen „der Wert der Variablen, deren Name in dieser Variablen steht“:

echo ${!n}
one

$(…) führt den in Klammern angegebenen Befehl in einer Subshell aus (d. h. in einem separaten Prozess, der alle Einstellungen wie Variablenwerte von der aktuellen Shell erbt) und sammelt seine Ausgabe. Also echo $($n) läuft $n als Shell-Befehl und zeigt seine Ausgabe an. Seit $n ergibt 1 , $($n) versucht, den Befehl 1 auszuführen , die nicht existiert.

eval echo \${$n} führt die an eval übergebenen Parameter aus . Nach der Erweiterung sind die Parameter echo und ${1} . Also eval echo \${$n} führt den Befehl echo ${1} aus .

Beachten Sie, dass Sie die meiste Zeit doppelte Anführungszeichen um Variablenersetzungen und Befehlsersetzungen verwenden müssen (d. h. immer wenn ein $ steht ):"$foo", "$(foo)" . Setzen Sie Variablen- und Befehlsersetzungen immer in doppelte Anführungszeichen , es sei denn, Sie wissen, dass Sie sie weglassen müssen. Ohne die doppelten Anführungszeichen führt die Shell eine Feldaufteilung durch (d. h. sie teilt den Wert der Variablen oder die Ausgabe des Befehls in separate Wörter auf) und behandelt dann jedes Wort als Platzhaltermuster. Zum Beispiel:

$ ls
file1 file2 otherfile
$ set -- 'f* *'
$ echo "$1"
f* *
$ echo $1
file1 file2 file1 file2 otherfile
$ n=1
$ eval echo \${$n}
file1 file2 file1 file2 otherfile
$eval echo \"\${$n}\"
f* *
$ echo "${!n}"
f* *

eval wird nicht sehr oft verwendet. In einigen Shells besteht die häufigste Verwendung darin, den Wert einer Variablen zu erhalten, deren Name bis zur Laufzeit nicht bekannt ist. In der Bash ist dies dank ${!VAR} nicht notwendig Syntax. eval ist immer noch nützlich, wenn Sie einen längeren Befehl erstellen müssen, der Operatoren, reservierte Wörter usw. enthält.


Stellen Sie sich eval einfach so vor, dass Sie „Ihren Ausdruck vor der Ausführung ein weiteres Mal auswerten“

eval echo \${$n} wird zu echo $1 nach der ersten Bewertungsrunde. Drei Änderungen zu beachten:

  • Die \$ wurde zu $ (Der umgekehrte Schrägstrich wird benötigt, ansonsten wird versucht, ${$n} auszuwerten , was eine Variable namens {$n} bedeutet , was nicht erlaubt ist)
  • $n wurde zu 1 ausgewertet
  • Der eval verschwunden

In der zweiten Runde ist es im Grunde echo $1 die direkt ausgeführt werden können.

Also eval <some command> wertet zuerst <some command> aus (mit auswerten meine ich hier Variablen ersetzen, maskierte Zeichen durch die richtigen ersetzen usw.) und dann den resultierenden Ausdruck noch einmal ausführen.

eval wird verwendet, wenn Sie Variablen dynamisch erstellen oder Ausgaben von Programmen lesen möchten, die speziell dafür entwickelt wurden, so gelesen zu werden. Beispiele finden Sie unter http://mywiki.wooledge.org/BashFAQ/048. Der Link enthält auch einige typische Möglichkeiten, wie eval verwendet wird, und die damit verbundenen Risiken.


Meiner Erfahrung nach besteht eine "typische" Verwendung von eval darin, Befehle auszuführen, die Shell-Befehle zum Setzen von Umgebungsvariablen generieren.

Vielleicht haben Sie ein System, das eine Sammlung von Umgebungsvariablen verwendet, und Sie haben ein Skript oder Programm, das festlegt, welche gesetzt werden sollen und welche Werte sie haben. Jedes Mal, wenn Sie ein Skript oder Programm ausführen, wird es in einem gegabelten Prozess ausgeführt, sodass alles, was es direkt mit Umgebungsvariablen macht, beim Beenden verloren geht. Aber dieses Skript oder Programm kann die Exportbefehle an stdout senden.

Ohne eval müssten Sie stdout in eine temporäre Datei umleiten, die temporäre Datei beziehen und sie dann löschen. Mit eval können Sie einfach:

eval "$(script-or-program)"

Beachten Sie, dass die Anführungszeichen wichtig sind. Nehmen Sie dieses (erfundene) Beispiel:

# activate.sh
echo 'I got activated!'

# test.py
print("export foo=bar/baz/womp")
print(". activate.sh")

$ eval $(python test.py)
bash: export: `.': not a valid identifier
bash: export: `activate.sh': not a valid identifier
$ eval "$(python test.py)"
I got activated!

Linux
  1. Zwei großartige Anwendungen für den cp-Befehl:Bash-Shortcuts

  2. Unterschied zwischen ' und ' in der Befehlszeile (bash)??

  3. Warum sollte eval in Bash vermieden werden und was sollte ich stattdessen verwenden?

  4. bash-Alias-Befehl mit einfachen und doppelten Anführungszeichen

  5. Was ist der Unterschied zwischen &> und >&in bash?

Bash-Quellbefehl

Verlaufsbefehl in Linux (Bash-Verlauf)

Bash Exit-Befehl und Exit-Codes

Bash-printf-Befehl

So lesen Sie die Ausgabe und Verwendung von Linux Top Command

Bash-Skripting (II)