Każda z konstrukcji zagnieżdżonych, które mogą być interpolowane wewnątrz łańcuchów, może zawierać w sobie dalsze łańcuchy: są one przetwarzane jak nowy skrypt, aż do znacznika zamykającego, a nawet mogą być zagnieżdżone na wielu poziomach głębokości. Wszystkie takty jednego z nich zaczyna się od $
. Wszystkie są udokumentowane w połączeniu instrukcji Bash i specyfikacji języka poleceń powłoki POSIX.
Istnieje kilka przypadków tych konstrukcji:
Zastąpienie poleceń$( ... )
, jak już znalazłeś. POSIX określa to zachowanie :
W $(command)
formularzu wszystkie znaki następujące po otwartym nawiasie do pasującego nawiasu zamykającego stanowią polecenie. Do polecenia można użyć dowolnego poprawnego skryptu powłoki ...
Cytaty są częścią prawidłowych skryptów powłoki, więc są dozwolone w ich normalnym znaczeniu.
- Zastępowanie poleceń
`
również.
Element „word” zaawansowanych instancji podstawiania parametrów, takich jak${parameter:-word}
. Definicja „słowo” jest :
Sekwencja znaków traktowana przez powłokę jako jednostka
- który zawiera cytowany tekst, a nawet mieszane cytaty a"b"c'd'e
- chociaż rzeczywiste zachowanie rozszerzeń jest nieco bardziej liberalne i na przykład ${x:-hello world}
działa również.
Rozwinięcie arytmetyczne z $(( ... ))
, chociaż tam jest w dużej mierze bezużyteczne (ale można zagnieżdżać podstawianie poleceń lub rozszerzenia zmiennych, a następnie użyteczne w nich cudzysłowy). POSIX stwierdza, że :
Wyrażenie traktuje się tak, jakby było w cudzysłowie, z tym wyjątkiem, że podwójny cudzysłów w wyrażeniu nie jest traktowany specjalnie. Powłoka powinna rozwinąć wszystkie tokeny w wyrażeniu w celu rozszerzenia parametrów, podstawiania poleceń i usuwania cytatów.
więc to zachowanie jest wyraźnie wymagane. Oznacza to echo "abc $((4 "*" 5))"
raczej arytmetykę niż globowanie.
Zauważ jednak, że interpretacja $[ ... ]
arytmetyczna w starym stylu nie jest traktowana w ten sam sposób: cudzysłowy będą błędem, jeśli się pojawią, niezależnie od tego, czy rozwinięcie jest cytowane, czy nie. Ten formularz nie jest już w ogóle dokumentowany i i tak nie jest przeznaczony do użycia.
- Tłumaczenie specyficzne dla ustawień narodowych za pomocą
$"..."
, które faktycznie używa "
jako podstawowego elementu. $"
jest traktowany jako jedna jednostka.
Jest jeszcze jeden przypadek zagnieżdżenia, którego można się nie spodziewać, nie obejmujący cudzysłowów, który dotyczy rozszerzenia nawiasów : {a,b{c,d},e}
rozwija się do „a bc bd e”.${x:-a{b,c}d}
robi nie gniazdo, jednak; jest traktowane jako podstawienie parametru, podając „ a{b,c
”, a następnie „ d}
”. Jest to również udokumentowane :
Gdy używane są nawiasy klamrowe, pasujący nawias końcowy jest pierwszym znakiem „}”, który nie jest poprzedzany ukośnikiem odwrotnym ani w cudzysłowie, ani w osadzonym rozszerzeniu arytmetycznym, podstawianiu poleceń lub rozszerzaniu parametrów.
Zasadniczo wszystkie konstrukcje rozdzielane parsują swoje ciała niezależnie od otaczającego kontekstu (i wyjątki są traktowane jak błędy ). Zasadniczo po zobaczeniu $(
kodu zastępującego polecenie prosi analizator składni, aby zużył tyle, ile może z ciała, jakby to był nowy program, a następnie sprawdza, czy oczekiwany znacznik kończący (nieskalowany )
lub ))
lub }
) pojawia się po uruchomieniu podparsera z rzeczy, które może konsumować.
Jeśli myślisz o działaniu parsera rekurencyjno-opadającego , jest to zwykła rekurencja do przypadku podstawowego. W rzeczywistości jest to łatwiejsze niż w inny sposób, gdy w ogóle masz interpolację łańcuchów. Bez względu na podstawową technikę analizowania, powłoki obsługujące te konstrukty dają ten sam wynik.
Możesz zagnieżdżać cytaty tak głęboko, jak chcesz w tych konstrukcjach i będzie działać zgodnie z oczekiwaniami. Nigdzie nie pomylić, widząc cytat na środku; zamiast tego będzie to początek nowego cytowanego ciągu w kontekście wewnętrznym.