Kontynuacja części podstawowej tego pytania .
W bash
mogę użyć ${!FOO}
do podwójnej zamiany, w zsh
${(P)FOO}
. W obu działa stara szkoła (hack-y) eval \$$FOO
.
Najmądrzejszą i najbardziej logiczną rzeczą byłoby dla mnie ${${FOO}}, ${${${FOO}}}…
zastąpienie podwójnym / potrójnym / n. Dlaczego to nie działa zgodnie z oczekiwaniami?
Po drugie: co robi \
w eval
oświadczeniu? Myślę, że to ucieczka, która uniemożliwia coś takiego eval \$$$FOO
. Jak zrobić potrójne / n podstawienie, które działa w każdej powłoce?
bash
zsh
variable-substitution
Profpatsch
źródło
źródło
l3=l2; eval eval eval echo \\\$\\$\$$l3
→53294
więc nie do końca modułowy.eval $(eval echo \$$l2)
? Nienawidzę bashu, to absolutnie nie ma sensu.źródło
Załóżmy, że wartość
FOO
jest poprawną nazwą zmiennej (powiedzmyBAR
),eval \$$FOO
dzieli wartośćBAR
na osobne słowa, traktuje każde słowo jako wzór wieloznaczny i wykonuje pierwsze słowo wyniku jako polecenie, przekazując pozostałe słowa jako argumenty. Odwrotny ukośnik przed dolarem powoduje, że jest traktowany dosłownie, więc argumentem przekazanym doeval
wbudowanego jest ciąg czterech znaków$BAR
.${${FOO}}
jest błędem składni. Nie wykonuje „podwójnego podstawienia”, ponieważ nie ma takiej funkcji w żadnej z popularnych powłok (zresztą i tak przy tej składni). W zsh${${FOO}}
jest poprawny i jest podwójnym podstawieniem, ale zachowuje się inaczej niż chcesz: wykonuje dwie kolejne transformacje na wartościFOO
, obie są transformacją tożsamości, więc jest to tylko fantazyjny sposób pisania${FOO}
.Jeśli chcesz traktować wartość zmiennej jako zmienną, uważaj na prawidłowe cytowanie. O wiele łatwiej jest ustawić wynik na zmienną:
źródło
{ba,z}sh
rozwiązanieOto funkcja, która działa w obu przypadkach
{ba,z}sh
. Wierzę, że jest również zgodny z POSIX.Nie wariując na cytowanie, możesz użyć go na wielu poziomach pośrednich, takich jak:
Lub jeśli masz więcej (!?!) Poziomów pośrednich, możesz użyć pętli.
Ostrzega, gdy podano:
źródło
Podobnie jak
${$foo}
nie działa w miejsce${(P)foo}
wzsh
, ani nie${${$foo}}
. Musisz tylko określić każdy poziom pośredni:Oczywiście
${!${!foo}}
nie działabash
, ponieważbash
nie pozwala na zagnieżdżone podstawienia.źródło
zsh
jest instalowany znacznie częściej, niż możesz przypuszczać. Może nie byćsh
takbash
często (ale nie zawsze) powiązany , ale wciąż może być dostępny dla skryptów powłoki. Pomyśl o tym jak o Perlu lub Pythonie.Dlaczego miałbyś to robić?
Zawsze możesz to zrobić w kilku krokach, takich jak:
Lub użyj funkcji takiej jak:
Następnie:
FWIW, w
zsh
:źródło
Rozwiązanie POSIX
Bez szaleństwa cytowania możesz użyć tej funkcji do wielu poziomów pośrednich, takich jak:
Lub jeśli masz więcej (!?!) Poziomów pośrednich, możesz użyć pętli.
Ostrzega, gdy podano:
źródło