Ein guter Weg, um damit zu arbeiten, evalbesteht darin, es echozu Testzwecken zu ersetzen . echound evalarbeiten genauso (wenn wir die \xErweiterung durch einige echoImplementierungen 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 bashspezifisch 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 fooVariable local to setvarso nutzlos wäre.
bash-4.2hinzugefügt , um eine -gOption für declareein erklären , global , variabel , aber das ist nicht das, was wir entweder als unser wollen setvareinen 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 declareaufgerufen wird declare( bashdas Konzept wurde tatsächlich aus dem typesetBuildin der Korn-Shell entlehnt), wenn die Variable bereits festgelegt ist, declarekeine 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 varnamees zuvor als Skalar , Array oder assoziatives Array deklariert wurde .
evaldiese Weise ist falsch. Sie erweitern,$var_valuebevor Sie es übergeben,evalwas bedeutet, dass es als Shell-Code interpretiert wird! (versuchen Sie es zum Beispiel mitvar_value="';:(){ :|:&};:'")