Çalışmanın iyi bir yolu, evalonu echotest için değiştirmektir . echove evalaynı şekilde çalışın ( bazı koşullar altında olduğu gibi \xbazı echouygulamalar tarafından yapılan genişletmeyi bir kenara bırakırsak bash).
Her iki komut da argümanlarını aralarındaki bir boşlukla birleştirir. Fark olduğunu echo gösterir sonuç ise eval değerlendirir / yorumlayan ve kabuk kodu olarak sonuçlanır.
Hangi kabuk kodunu görmek için
eval $(echo $var_name=$var_value)
değerlendirirseniz, şunları çalıştırabilirsiniz:
$ echo $(echo $var_name=$var_value)
fruit=blue orange
İstediğiniz bu değil, istediğiniz şey:
fruit=$var_value
Ayrıca, $(echo ...)burada kullanmak mantıklı değil.
Yukarıdakilerin çıktısını almak için şunu çalıştırırsınız:
$ echo "$var_name=\$var_value"
fruit=$var_value
Yani, yorumlamak için, bu basitçe:
eval "$var_name=\$var_value"
Tek tek dizi öğelerini ayarlamak için de kullanılabileceğini unutmayın:
var_name='myarray[23]'
var_value='something'
eval "$var_name=\$var_value"
Diğerlerinin söylediği gibi, kodunuzun bashspesifik olmasını umursamıyorsanız , aşağıdaki gibi kullanabilirsiniz declare:
declare "$var_name=$var_value"
Ancak bazı yan etkileri olduğunu unutmayın.
Değişkenin kapsamını çalıştığı işlevle sınırlar. Böylece, örneğin aşağıdaki gibi şeyleri kullanamazsınız:
setvar() {
var_name=$1 var_value=$2
declare "$var_name=$var_value"
}
setvar foo bar
Çünkü bu fooyerel değişkenin böyle olacağını açıklayamaz setvar.
bash-4.2global bir değişken bildirmek -giçin bir seçenek ekledik , ancak arayan bir işlevse, arayanınkine göre global bir değişken belirleyeceğimiz için istediğimiz şey bu değildi :declaresetvar
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"
hangi çıktı:
1:
2: some value
Ayrıca, declaredeğişken çağrılmışsa declare(aslında bashkavramı Korn kabuğunun typesetyerleşikinden ödünç alınmış) çağrılırsa , declareyeni bir değişken bildirmez ve atamanın yapılma şekli değişkenin türüne bağlıdır.
Örneğin:
varname=foo
varvalue='([PATH=1000]=something)'
declare "$varname=$varvalue"
varnameönceden skaler , dizi veya ilişkilendirilebilir dizi olarak bildirilmişse farklı bir sonuç üretir (ve muhtemelen kötü yan etkilere sahiptir) .
evalBu şekilde kullanmak yanlıştır. Onu$var_valuegeçmeden önce genişliyorsunuz ,evalyani kabuk kodu olarak yorumlanacak! (örneğin ile deneyinvar_value="';:(){ :|:&};:'")