Çalışmanın iyi bir yolu, eval
onu echo
test için değiştirmektir . echo
ve eval
aynı şekilde çalışın ( bazı koşullar altında olduğu gibi \x
bazı echo
uygulamalar 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 bash
spesifik 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 foo
yerel değişkenin böyle olacağını açıklayamaz setvar
.
bash-4.2
global bir değişken bildirmek -g
iç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 :declare
setvar
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, declare
değişken çağrılmışsa declare
(aslında bash
kavramı Korn kabuğunun typeset
yerleşikinden ödünç alınmış) çağrılırsa , declare
yeni 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) .
eval
Bu şekilde kullanmak yanlıştır. Onu$var_value
geçmeden önce genişliyorsunuz ,eval
yani kabuk kodu olarak yorumlanacak! (örneğin ile deneyinvar_value="';:(){ :|:&};:'"
)