${!FOO}
melakukan substitusi ganda dalam bash
, yang berarti mengambil nilai (string) FOO dan menggunakannya sebagai nama variabel.
zsh
tidak mendukung fitur ini.
Apakah ada cara untuk membuat ini bekerja sama di bash
dan zsh
?
Latar Belakang:
Saya punya daftar variabel lingkungan, seperti
PATH MAIL EDITOR
dan ingin mencetak nama variabel terlebih dahulu dan kemudian nilainya.
Ini berfungsi bash
tetapi tidak zsh
:
for VAR in LIST
do
echo $VAR
echo ${!VAR}
done
Entah bagaimana itu mungkin menjadi "jalan lama" dengan eval
, tetapi saya tidak bisa membuatnya bekerja:
for VAR in LIST
do
echo $VAR
echo `eval \$$VAR`
done
Saya tidak akan pernah mengerti mengapa saya tidak bisa begitu saja melakukan substitusi mendalam seperti ${${VAR}}
atau bahkan ${${${VAR}}}
jika perlu, jadi penjelasan untuk itu juga bagus.
bash
zsh
variable-substitution
for
Profpatsch
sumber
sumber
bash
, ia memang memiliki fungsi yang sama (dan lebih banyak lagi), hanya menggunakan pola yang berbeda, yaitu${(p)FOO}
.(e)
flag ekspansi parameter zsh telah ditambahkan di zsh-2.6-beta17 (Mei 1996),(P)
flag dalam 3.1.5-pws-7 (1999). bash ada${!var}
di 2.0 (Desember 1996).Jawaban:
Baik bash dan zsh memiliki cara untuk melakukan ekspansi tidak langsung, tetapi mereka menggunakan sintaks yang berbeda.
Cukup mudah untuk melakukan ekspansi tidak langsung menggunakan
eval
; ini bekerja di semua shell POSIX dan sebagian besar Bourne. Berhati-hatilah untuk mengutip dengan benar jika nilainya mengandung karakter yang memiliki arti khusus dalam shell.${${VAR}}
tidak berfungsi karena itu bukan fitur yang diterapkan shell. Hal di dalam kurung harus sesuai dengan aturan sintaksis yang tidak termasuk${VAR}
. (Dalam zsh, ini adalah sintaks yang didukung, tetapi melakukan sesuatu yang berbeda: substitusi bersarang melakukan transformasi berturut-turut pada nilai yang sama;${${VAR}}
sama dengan$VAR
karena ini melakukan transformasi identitas dua kali pada nilainya.)sumber
Komentar, di bawah pertanyaan awal, oleh Profpatsch memberikan contoh
${(p)FOO}
untuk menampilkan konten dari referensi variabel tidak langsung. Bendera salah atau salah ketik, itu harus huruf kapital P dan bukan huruf kecil p. Gunakan:${(P)FOO}
.Berikut ini harus menghasilkan output yang diinginkan:
Dari halaman manual zshexpn ; bagian - Bendera Ekspansi Parameter :
Pada suatu waktu saya membaca mengapa
${${${VAR}}}
tidak menghasilkan output yang Anda harapkan, tetapi saat ini saya tidak dapat menemukannya. Anda dapat melakukan sesuatu seperti berikut ini:sumber
Anda tidak menggunakan eval dengan benar. Dalam nilai contoh Anda $ VAR diawali dengan "$" (yaitu `$ VALUE ') akan dieksekusi sebagai perintah. Bukan itu yang Anda inginkan. Anda ingin mengevaluasi perluasan variabel yang namanya diambil dari variabel lain.
sumber
{ba,z}sh
larutanInilah fungsi yang bekerja di {ba, z} sh. Saya percaya itu juga sesuai dengan POSIX.
Ini memperingatkan ketika diberikan:
sumber
function
atau tidak[[...]]
dalam POSIXsh
.[ "$#" -eq 0 ]
(atau mungkin[ "$#" -ne 1 ]
karena Anda hanya mengharapkan satu argumen).shell-check
mungkin membantu juga.${1-}
diberikana='"" -o -n 1'
[ -z $a ]
==0
. Tetapi tidak akan$#
selalu menjadi token tunggal?