Cara yang baik untuk bekerja evaladalah menggantinya dengan echountuk pengujian. echodan evalbekerja sama (jika kita menyisihkan \xekspansi yang dilakukan oleh beberapa echoimplementasi seperti bashdalam beberapa kondisi).
Kedua perintah bergabung dengan argumen mereka dengan satu spasi di antaranya. Perbedaannya adalah bahwa echo menampilkan hasil saat eval mengevaluasi / menginterpretasikan sebagai kode shell hasil.
Jadi, untuk melihat kode shell apa
eval $(echo $var_name=$var_value)
akan mengevaluasi, Anda dapat menjalankan:
$ echo $(echo $var_name=$var_value)
fruit=blue orange
Bukan itu yang Anda inginkan, yang Anda inginkan adalah:
fruit=$var_value
Juga, menggunakan di $(echo ...)sini tidak masuk akal.
Untuk menampilkan yang di atas, Anda akan menjalankan:
$ echo "$var_name=\$var_value"
fruit=$var_value
Jadi, untuk menafsirkannya, itu hanya:
eval "$var_name=\$var_value"
Perhatikan bahwa ini juga dapat digunakan untuk mengatur elemen array individual:
var_name='myarray[23]'
var_value='something'
eval "$var_name=\$var_value"
Seperti yang orang lain katakan, jika Anda tidak peduli kode Anda bashspesifik, Anda dapat menggunakan declaresebagai:
declare "$var_name=$var_value"
Namun perhatikan bahwa ia memiliki beberapa efek samping.
Ini membatasi ruang lingkup variabel ke fungsi di mana itu dijalankan. Jadi Anda tidak dapat menggunakannya misalnya dalam hal-hal seperti:
setvar() {
var_name=$1 var_value=$2
declare "$var_name=$var_value"
}
setvar foo bar
Karena itu akan mendeklarasikan foovariabel lokal setvarsehingga tidak akan berguna.
bash-4.2menambahkan -gopsi untuk declaremendeklarasikan variabel global , tapi bukan itu yang kita inginkan karena kita setvarakan menetapkan global var yang bertentangan dengan pemanggil jika pemanggil adalah fungsi, seperti di:
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"
yang akan menghasilkan:
1:
2: some value
Juga, perhatikan bahwa sementara declaredipanggil declare(sebenarnya bashmeminjam konsep dari typesetbuiltin shell Korn ), jika variabel sudah ditetapkan, declaretidak mendeklarasikan variabel baru dan cara tugas dilakukan tergantung pada jenis variabel.
Contohnya:
varname=foo
varvalue='([PATH=1000]=something)'
declare "$varname=$varvalue"
akan menghasilkan hasil yang berbeda (dan berpotensi memiliki efek samping buruk) jika varnamesebelumnya dinyatakan sebagai skalar , array , atau array asosiatif .
evalcara itu salah. Anda memperluas$var_valuesebelum meneruskannya keevalyang artinya akan ditafsirkan sebagai kode shell! (coba misalnya denganvar_value="';:(){ :|:&};:'")