Ein guter Weg, um damit zu arbeiten, eval
besteht darin, es echo
zu Testzwecken zu ersetzen . echo
und eval
arbeiten genauso (wenn wir die \x
Erweiterung durch einige echo
Implementierungen wie bash
's unter bestimmten Bedingungen aufheben).
Beide Befehle verbinden ihre Argumente mit einem Leerzeichen dazwischen. Der Unterschied besteht darin, dass das Ergebnis echo
angezeigt wird, während das Ergebnis als Shell-Code eval
ausgewertet / interpretiert wird .
Also, um zu sehen, welcher Shell-Code
eval $(echo $var_name=$var_value)
würde bewerten, können Sie ausführen:
$ echo $(echo $var_name=$var_value)
fruit=blue orange
Das ist nicht was du willst, was du willst ist:
fruit=$var_value
Auch $(echo ...)
hier macht es keinen Sinn.
Um das Obige auszugeben, würden Sie Folgendes ausführen:
$ echo "$var_name=\$var_value"
fruit=$var_value
Um es zu interpretieren, ist das einfach:
eval "$var_name=\$var_value"
Beachten Sie, dass damit auch einzelne Array-Elemente festgelegt werden können:
var_name='myarray[23]'
var_value='something'
eval "$var_name=\$var_value"
Wie andere bereits gesagt haben, können Sie Folgendes verwenden, wenn es Ihnen egal ist, ob Ihr Code bash
spezifisch ist declare
:
declare "$var_name=$var_value"
Beachten Sie jedoch, dass es einige Nebenwirkungen hat.
Der Gültigkeitsbereich der Variablen ist auf die Funktion beschränkt, in der sie ausgeführt wird. Sie können sie also beispielsweise nicht in folgenden Situationen verwenden:
setvar() {
var_name=$1 var_value=$2
declare "$var_name=$var_value"
}
setvar foo bar
Denn das würde deklarieren, dass eine foo
Variable local to setvar
so nutzlos wäre.
bash-4.2
hinzugefügt , um eine -g
Option für declare
ein erklären , global , variabel , aber das ist nicht das, was wir entweder als unser wollen setvar
einen würde gesetzt globalen var im Gegensatz zu dem dem Anrufer , wenn der Anrufer eine Funktion ist, wie in:
setvar() {
var_name=$1 var_value=$2
declare -g "$var_name=$var_value"
}
foo() {
local myvar
setvar myvar 'some value'
echo "1: $myvar"
}
foo
echo "2: $myvar"
was ausgeben würde:
1:
2: some value
Beachten Sie außerdem, dass while declare
aufgerufen wird declare
( bash
das Konzept wurde tatsächlich aus dem typeset
Buildin der Korn-Shell entlehnt), wenn die Variable bereits festgelegt ist, declare
keine neue Variable deklariert und die Art der Zuweisung vom Typ der Variablen abhängt.
Zum Beispiel:
varname=foo
varvalue='([PATH=1000]=something)'
declare "$varname=$varvalue"
wird ein anderes Ergebnis erzeugen (und möglicherweise böse Nebenwirkungen haben), wenn varname
es zuvor als Skalar , Array oder assoziatives Array deklariert wurde .
eval
diese Weise ist falsch. Sie erweitern,$var_value
bevor Sie es übergeben,eval
was bedeutet, dass es als Shell-Code interpretiert wird! (versuchen Sie es zum Beispiel mitvar_value="';:(){ :|:&};:'"
)