
Hier ist mein kleiner Bash-Skriptausschnitt.
i=5
command='echo $i'
$command
Ich möchte, dass dieses Skript druckt 5
, d. h., es soll „echo“ ausführen und „5“ drucken. Aber stattdessen druckt es immer weiter $i
. Wie kann ich das also lösen?
Antwort1
Das wäre:
eval "$command"
Wenn Sie möchten, dass der Inhalt $command
als Shellcode ausgewertet wird.
Wenn Sie nicht garantieren können, dass $command
es nicht mit beginnt -
(was eval
in einigen Shells dazu führen würde bash
, dass es als Option behandelt wird), möchten Sie möglicherweise Folgendes ausführen:
eval " $command"
stattdessen. Das zusätzliche Leerzeichen am Anfang hat keinen Einfluss auf die Art und Weise, wie der Befehl analysiert wird, und verhindert, $command
dass er als Option zu behandelt wird, eval
wenn er mit beginnt -
. eval -- "$command"
würde auch in einigen Shells (einschließlich ) funktionieren, ist aber nicht POSIX (IIRC) und würde beispielsweise bash
in oder der Bourne-Shell nicht funktionieren .dash
Beachten Sie, dass Ihr Name $command
wahrscheinlich lauten sollte:
command='echo "$i"'
Sofern Sie nicht beabsichtigt haben, $i
Split+Glob zu unterliegen
Eine möglicherweise bessere Möglichkeit, Code in „Variablen“ zu speichern, wäre die Verwendung von Funktionen:
mycommand() { echo "$i"; }
(verwenden Sie mycommand
anstelle von command
, da command
es sich bereits um einen vorhandenen Befehl handelt).
Wenn / / $command
ist , variiert das Verhalten je nach Shell.break
continue
return
Wenn Sie $command
eineeinfacher Befehl, das ist eine Liste von Wörtern, von denen das erste als der auszuführende Befehl mit der Liste der Wörter als Argumente nachgeschlagen wird. Sie würden eine Array-Variable verwenden:
command=('echo' '$i' "$i")
"${command[@]}"
Das würde ausführen echo
, mit echo
und $i
dem Inhalt von $i
als Argumente.
command='echo $i ;x /* '$i
$command
(mit dem Standardwert $IFS
) ist die, die am wenigsten Sinn ergeben würde. Dort $command
würde eine Zeichenfolge enthalten. Die erste $i
wird so belassen, wie sie ist, die zweite erweitert (außerhalb der einfachen Anführungszeichen), und dann würde diese Zeichenfolge split+glob unterzogen (außerhalb der $command
doppelten Anführungszeichen), was zu einer Anzahl von Wörtern führen würde, die alseinfacher Befehlwieder.