Na popiołu, biegu i uderzeniu, kiedy biegnę
$ echo ab$
powraca
ab$
Czy takie zachowanie jest określone przez POSIX, czy jest to tylko powszechna konwencja w powłokach zgodnych z POSIX? Nie mogłem znaleźć niczego na stronie języka poleceń powłoki POSIX, która wspomniałaby o tym zachowaniu.
$
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).ab$
nie ma znaku po nim$
, bez względu na to, czy po nim następował znak null w oryginalnym ciągu wejściowym czy spacja w przypadku jakecho ab$ foo
; oryginalna niecytowana biała spacja została rozpoznana i odrzucona po analizie.Odpowiedzi:
$
sam w sobie nie ma specjalnego znaczenia (tryecho $
), tylko w połączeniu z innym znakiem po nim i tworzącym rozwinięcie, np.$var
(lub${var}
)$(util)
,,$((1+2))
.$
Staje się jego „specjalny”, czyli jak definiowanie ekspansję w standardzie POSIX ramach sekcji Reklamowe Recognition :Jeśli więc
$
nie tworzy rozwinięcia, obowiązują inne reguły analizy:To obejmuje twój
ab$
sznurek.W przypadku samotnego
$
(„nowym słowem” byłoby$
samo w sobie):Znaczenie wytworzonego słowa zawierających
$
która nie jest średnia rozprężania wyraźnie zdefiniowane jako nieokreślone POSIX.Zauważ też, że
$
jest to ostatni znak$$
, ale zdarza się, że jest to zmienna, która przechowuje PID bieżącej powłoki. Wbash
,!$
może wywołać rozszerzenie historii (ostatni argument poprzedniej komendy). Ogólnie rzecz biorąc, nie,$
nie jest pozbawione znaczenia na końcu niecytowanego słowa, ale na końcu słowa przynajmniej nie oznacza standardowego rozwinięcia.źródło
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$
iecho $
.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 :
„Nieokreślony” jest tu szczególnym określeniem
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 (@
,*
,#
,?
,-
,$
,!
, lub0
), 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śloneecho a$ b
: wyjście literału, w pełni określoneecho a$ b$
: wyjście literału, w pełni określoneecho a$b
: rozszerzenie parametrub
, w pełni określoneecho a$-b
: rozszerzenie parametru specjalnego-
, w pełni określoneecho a$+b
: nieokreślone zachowanieecho "a$ b"
: nieokreślone zachowanieNa
$
końcu słowa możesz polegać na zachowaniu, które musi być traktowane dosłownie i przekazywaneecho
poleceniu jako część jego argumentu. Jest to wymóg zgodności z powłoką.źródło
echo $
również dosłowny i w pełni określony?echo "$"
i gdzieecho "a b$"
spaść?