Czytam „ Bash Guide for Beginners ”. To mówi:
Jeśli pierwszy znak
PARAMETER
jest wykrzyknikiem, Bash używa wartości zmiennej utworzonej z resztyPARAMETER
jako nazwy zmiennej; ta zmienna jest następnie interpretowana i ta wartość jest używana w pozostałej części podstawiania, a nie jako wartośćPARAMETER
sama w sobie. Jest to znane jako ekspansja pośrednia.
Podany przykład to:
franky ~> echo ${!N*}
NNTPPORT NNTPSERVER NPX_PLUGIN_PATH
Nie całkiem rozumiem tutaj:
wartość zmiennej utworzonej z reszty
PARAMETER
Ponieważ PARAMETER
to właśnie !N*
, a następnie
reszta
PARAMETER
jest po prostu N*
. Jak to może tworzyć zmienną? Czy Bash przeszukał tam wszystkie możliwe polecenia?
źródło
Wydaje się, że istnieje wyjątek, gdy dane „pośrednie” kończy się na a
*
, tak jak ma to miejsce w tym przypadku. W tym przypadku podaje wszystkie nazwy zmiennych zaczynające się od określonej części (N
tutaj). Bash może to zrobić, ponieważ śledzi zmienne i wie, które z nich istnieją.Prawdziwe pośrednie jest to:
powiedzmy, że mam
$VARIABLE
ustawioną zmienną42
i mam inną zmienną$NAME
ustawioną naVARIABLE
.${!NAME}
da mi42
. Używasz wartości jednej zmiennej, aby podać nazwę innej:$ NAME="VARIABLE" $ VARIABLE=42 $ echo ${!NAME} 42
źródło
Tak, wyszukuje wszystkie możliwe rozszerzenia zmiennych po!. Jeśli zrobiłeś:
echo ${!NP*}
dostaniesz tylko
NPX_PLUGIN_PATH
.Rozważmy następujący przykład:
:~> export myVar="hi" :~> echo ${!my*} myVar :~> export ${!my*}="bye" :~> echo $myVar bye
źródło
${!my*}
rozszerza się do myA, myB, myA jest eksportowane ze swoją bieżącą wartością, a myB jest ustawione na „bye” i wyeksportowane. Niezbyt przydatne.Trafiłeś w wyjątek w przetwarzaniu pośrednim, gdzie jeśli ostatnim znakiem jest
*
, zwrócone zostaną wszystkie zmienne, które mają wcześniej podany prefiks.źródło
*
przypadkiem, czy to to samo co${${VAR}}
?${${VAR}}
możliwością zapisu, ponieważ${$VAR}
nie jest legalne, ponieważ$VAR
zwraca ciąg znaków, który nie może występować po$
znaku; aby użyć łańcucha jako nazwy zmiennej, musisz wprowadzić jeden poziom pośredni (jak podano w samym oryginalnym pytaniu), tj. możesz użyć${!VAR}
, który robi dokładnie to, czego się spodziewałeś (błędnie, ale zrozumiale)${$VAR}
.Możesz odnieść się do tego dokumentu GNU w celu uzyskania informacji na temat basha
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html#Shell-Parameter-Expansion
Ale zasadniczo ekspansja pośrednia nie jest wykonywana
${!prefix*}
jako jeden z wyjątków, w twoim przykładzie N jest przedrostkiem.Dokument wyjaśni, czym jest ekspansja pośrednia w bash
źródło