2011-01-12 13 views

Antwort

67

Unix-Shells führen eine Reihe von Transformationen auf jeder Eingabezeile aus, bevor sie ausgeführt werden. Für die meisten Schalen sieht es so etwas wie dieses (vom bash manpage genommen):

  • anfängliche Wort Spaltung
  • Klammer Expansion
  • Tilde-Erweiterung
  • Parameter, variable und arithmetische Erweiterung
  • Befehl Ersatz
  • sekundäre Wortaufteilung
  • Pfad e xpansion (aka Globbing)
  • Zitat Entfernung

Mit $cmd direkt durch Ihren Befehl während der Parameter Expansionsphase ersetzt wird, und es durchläuft dann alle folgenden Transformationen.

Mit eval "$cmd" tut nichts, bis der Zitat Entfernungsphase, wo $cmd wie zurückgegeben wird und als Parameter an eval übergeben, deren Funktion es ist wieder die gesamte Kette laufen vor der Ausführung.

Sie sind also in den meisten Fällen identisch und unterscheiden sich, wenn Ihr Befehl die Umwandlungsschritte bis zur Parametererweiterung verwendet. Beispiel: Verwenden der Klammererweiterung:

$ cmd="echo foo{bar,baz}" 
$ $cmd 
foo{bar,baz} 
$ eval "$cmd" 
foobar foobaz 
+5

Wie macht man 'eval" $ cmd "' ohne 'eval' zu schreiben?' $ ($ Cmd) '' '$ {$ cmd}'? –

+2

@StevenLu, keine davon ist äquivalent - absichtlich so: Ein 'eval "Die Operation analysiert Daten als Syntax, ist also sehr sicherheitsempfindlich und würde implizit eine sehr schlechte Form haben. –

-2

Ich denke, yu setzen `Symbole um Ihre Variable (der mit ~ wenn die Umschalttaste gedrückt wird)

+3

Dies führt die Ausgabe des Befehls aus, der z.B. im Fall von ls -l wird eine Nachricht wie "total" Befehl nicht gefunden "(weil total ... ist Teil der Ausgabe von ls -l, zB) Also das ist nicht, was Sie wollen. –

3

Wenn Sie gerade tun eval $cmd wenn wir das tun cmd="ls -l" (interaktiv und in einem Skript) erhalten wir die erwünschtes Ergebnis. In deinem Fall hast du eine Pipe mit einem Grep ohne Muster, so dass der Grep-Teil mit einer Fehlermeldung fehlschlägt. Nur $cmd wird eine Nachricht "Befehl nicht gefunden" (oder einige solche) generieren. Versuchen Sie also, eval zu verwenden, und verwenden Sie einen beendeten Befehl, nicht einen, der eine Fehlermeldung generiert.

+0

Es war nur Druckfehler Sollte "grep exception" sein. –

+0

dann benutze eval, nicht $ cmd von selbst, da es wahrscheinlich nicht funktioniert (es hat nicht in meinen Tests unter bash und zsh). Das ist was eval zu tun war ... –

Verwandte Themen