W zależności od dokładnej sytuacji jest to albo jawnie nieokreślone (więc implementacje mogą robić, co chcą), albo wymagane, aby tak się stało. W swoim dokładnym scenariuszem echo ab$
, POSIX nakazuje wyjście „ab $”, który obserwuje i nie jest nieokreślona . Szybkie podsumowanie wszystkich różnych przypadków znajduje się na końcu.
Istnieją dwa elementy: najpierw tokenizowanie na słowa, a następnie interpretacja tych słów.
Tokenizacja
Tokenizacja POSIX wymaga, aby a, $
który nie jest początkiem prawidłowego rozszerzenia parametru , podstawienia polecenia lub podstawienia arytmetycznego, był uważany za dosłowną część WORD
budowanego tokena. Wynika to z reguły 5 („Jeśli bieżący znak jest niecytowany $
lub `
, powłoka rozpoznaje początek dowolnych kandydatów do interpretacji parametrów, podstawiania poleceń lub interpretacji arytmetycznej na podstawie ich wprowadzających, niecytowanych sekwencji znaków: $
lub ${
, $(
lub `
, i $((
, odpowiednio” ) nie ma zastosowania, ponieważ żadne z tych rozszerzeń nie jest tam wykonalne. Rozwinięcie parametrów wymaga pojawienia się tam poprawnej nazwy, a pusta nazwa nie jest poprawna.
Ponieważ ta zasada nie miała zastosowania, kontynuujemy jej przestrzeganie, dopóki nie znajdziemy takiej, która ją spełnia. Dwaj kandydaci to # 8 („Jeśli poprzedni znak był częścią słowa, bieżący znak zostanie dołączony do tego słowa.”) I nr 10 („Bieżący znak jest używany jako początek nowego słowa.”) , które dotyczą odpowiednio echo a$
i echo $
.
Istnieje również trzeci przypadek formy, echo a$+b
która przechodzi przez to samo pęknięcie, ponieważ +
nie jest to nazwa specjalnego parametru. Do tego wrócimy później, ponieważ uruchamia różne części reguł.
Specyfikacja wymaga zatem, aby $
była uważana za część słowa składniowo, a następnie może być dalej przetwarzana.
Rozwijanie wyrazów
Po przeanalizowaniu danych wejściowych w ten sposób, z $
zawartym w nim słowem, do każdego z przeczytanych słów stosowane są rozwinięcia słów. Każde słowo jest przetwarzane indywidualnie .
Określono, że :
Jeśli po nie cytowanym znaku „$” występuje znak, który nie jest jednym z poniższych:
- Znak numeryczny
- Nazwa jednego z parametrów specjalnych (patrz Parametry specjalne )
- Prawidłowy pierwszy znak nazwy zmiennej
- A
<left-curly-bracket>
(„{”)
- ZA
<left-parenthesis>
wynik jest nieokreślony.
„Nieokreślony” jest tu szczególnym określeniem
- W tym przypadku zgodna powłoka może wybrać dowolne zachowanie
- Zgodna aplikacja nie może polegać na żadnym konkretnym zachowaniu
W przykładzie echo ab$
, $
nie następuje dowolnym charakterze , więc zasada ta nie ma zastosowania, a nieokreślone wynik nie jest wywoływany. Po prostu nie ma na to żadnego rozszerzenia $
, więc jest dosłownie obecny i wydrukowany.
Gdzie byłoby zastosować w naszym trzecim przypadku z góry: echo a$+b
. Tutaj $
następuje +
, która nie jest liczbą, specjalny parametr ( @
, *
, #
, ?
, -
, $
, !
, lub 0
), zacznij od zmiennej nazwy (podkreślenia lub alfabetycznym z przenośnego zestawu znaków ), lub jeden z uchwytów. W tym przypadku zachowanie jest nieokreślony: a powłoka zgodna jest dozwolone wynaleźć specjalny parametr zwany +
poszerzyć i zgodny wniosek nie należy zakładać, że powłoka nie . Powłoka mogłaby również robić wszystko, co lubiła, w tym zgłaszać błąd.
Na przykład, zsh, w tym w trybie POSIX, interpretuje $+b
jako „ b
zestaw zmiennych ” i zastępuje 1 lub 0 zamiast niego. Podobnie ma rozszerzenia dla ~
i =
. To jest zgodne zachowanie.
Innym miejscem, w którym może się to zdarzyć, jest echo "a$ b"
. Ponownie, powłoka może robić, co chce, a ty jako autor skryptu powinieneś uciec, $
jeśli chcesz dosłowny wynik. Jeśli tego nie zrobisz, może działać, ale nie możesz na nim polegać. Jest to bezwzględna litera specyfikacji, ale nie sądzę, aby ten rodzaj szczegółowości był zamierzony lub rozważany.
W podsumowaniu
echo ab$
: wyjście literału, w pełni określone
echo a$ b
: wyjście literału, w pełni określone
echo a$ b$
: wyjście literału, w pełni określone
echo a$b
: rozszerzenie parametru b
, w pełni określone
echo a$-b
: rozszerzenie parametru specjalnego -
, w pełni określone
echo a$+b
: nieokreślone zachowanie
echo "a$ b"
: nieokreślone zachowanie
Na $
końcu słowa możesz polegać na zachowaniu, które musi być traktowane dosłownie i przekazywane echo
poleceniu jako część jego argumentu. Jest to wymóg zgodności z powłoką.
$
nabiera specjalnego znaczenia, jeśli jest to ostatni znak w słowie?” Nie przypisano żadnego specjalnego znaczenia$
; służy do wprowadzania wielu, ale odrębnych rozszerzeń, takich jak interpretacja parametrów${...}
, podstawianie poleceń$(...)
i wyrażenia arytmetyczne$((...))
. Niektóre powłoki wprowadzają dodatkowe konteksty, takie jakksh
wariant zastępowania poleceńx=${ echo foo; echo bar;}
(który różni się od standardu,$(...)
ponieważ nie wykonuje poleceń w podpowłoce).