Tindak lanjuti bagian latar belakang dalam pertanyaan ini .
Di bash
saya bisa gunakan ${!FOO}
untuk substitusi ganda, di zsh
${(P)FOO}
. Dalam keduanya, old-school (hack-y) eval \$$FOO
berfungsi.
Jadi, hal yang paling cerdas dan paling logis bagi saya adalah ${${FOO}}, ${${${FOO}}}…
substitusi ganda / tripel / n. Mengapa ini tidak bekerja seperti yang diharapkan?
Kedua: Apa yang \
dilakukan dalam eval
pernyataan itu? Saya pikir itu pelarian, membuat sesuatu yang eval \$$$FOO
mustahil. Bagaimana melakukan substitusi tripel / n dengan yang bekerja di setiap shell?
sumber
l3=l2; eval eval eval echo \\\$\\$\$$l3
→53294
jadi tidak persis modular.eval $(eval echo \$$l2)
? Aku benci pesta, itu sama sekali tidak masuk akal.sumber
Misalkan nilai
FOO
adalah nama variabel yang valid (katakanlahBAR
), pisahkaneval \$$FOO
nilaiBAR
menjadi kata-kata yang terpisah, perlakukan setiap kata sebagai pola wildcard, dan jalankan kata pertama dari hasil sebagai perintah, dengan kata lain sebagai argumen. Garis miring terbalik di depan dolar membuatnya diperlakukan secara harfiah, sehingga argumen yang diteruskan keeval
builtin adalah string empat karakter$BAR
.${${FOO}}
adalah kesalahan sintaksis. Itu tidak melakukan "substitusi ganda" karena tidak ada fitur seperti itu di shell umum (tidak dengan sintaks ini pula). Dalam zsh,${${FOO}}
adalah sah dan merupakan substitusi ganda, tetapi berperilaku berbeda dari apa yang Anda ingin: ia melakukan dua transformasi berturut-turut pada nilaiFOO
, yang keduanya transformasi identitas, sehingga hanya cara mewah untuk menulis${FOO}
.Jika Anda ingin memperlakukan nilai suatu variabel sebagai variabel, berhati-hatilah untuk mengutip sesuatu dengan benar. Jauh lebih mudah jika Anda mengatur hasilnya ke variabel:
sumber
{ba,z}sh
larutanInilah fungsi yang bekerja di keduanya
{ba,z}sh
. Saya percaya itu juga sesuai dengan POSIX.Tanpa tergila-gila dengan mengutip, Anda dapat menggunakannya untuk banyak tingkat tipuan seperti:
Atau jika Anda memiliki lebih banyak tingkat tipu daya (!?!) Anda bisa menggunakan loop.
Ini memperingatkan ketika diberikan:
sumber
Sama seperti
${$foo}
tidak bekerja di tempat${(P)foo}
dizsh
, juga tidak${${$foo}}
. Anda hanya perlu menentukan setiap tingkat tipuan:Tentu saja,
${!${!foo}}
tidak berfungsibash
, karenabash
tidak memungkinkan penggantian tersarang.sumber
zsh
diinstal jauh lebih sering daripada yang Anda duga. Ini mungkin tidak terhubung dengansh
sukabash
sering (tapi tidak selalu), tetapi mungkin masih tersedia untuk skrip shell. Anggap saja seperti yang Anda lakukan Perl atau Python.Mengapa Anda perlu melakukan itu?
Anda selalu dapat melakukannya dalam beberapa langkah seperti:
Atau gunakan fungsi seperti:
Kemudian:
FWIW, di
zsh
:sumber
Solusi POSIX
Tanpa tergila-gila dengan mengutip, Anda dapat menggunakan fungsi ini untuk banyak tingkat tipuan seperti:
Atau jika Anda memiliki lebih banyak tingkat tipu daya (!?!) Anda bisa menggunakan loop.
Ini memperingatkan ketika diberikan:
sumber