Twoje pierwsze przypuszczenie było słuszne, ale użyłeś złego przykładu. Gdy powłoka odczytuje polecenie
foo=bar echo $foo
pierwszą rzeczą, jaką robi (lub przynajmniej jedną z pierwszych rzeczy) jest poszukiwanie referencji zmiennych (jak $foo
) i ich ocena.
Następnie przetwarza to, co zostało z linii. (Może to być trochę nadmierne uproszczenie; szczegółowe informacje można znaleźć bash(1)
w Instrukcji obsługi Bash ). Masz więc polecenie
echo (nic)
biegać z foo=bar
; ale jest za późno; nie ma już nic, na co można spojrzeć $foo
. Możesz to zademonstrować za pomocą następującej sekwencji:
$ foo=oldvalue
$ foo=bar echo "$foo"
oldvalue
Ale
polecenie foo = bar
jest droga. Oto kilka przykładów, które działają:
foo=bar sh -c 'echo "$foo"'
i
foo=bar env
(Możesz to przepuścić grep foo
).
Właśnie zauważyłem cytowane zdanie: „Gdy te instrukcje przypisania poprzedzają polecenie wbudowane w powłokę, na przykład…”, sugerując, że wbudowane polecenia (takie jak echo
) reprezentują szczególny przypadek. Jest dla mnie intuicyjne (przynajmniej dla mnie), że ten „zakres poleceń”, którego szukasz, musiałby działać, ustawiając zmienną środowiskową w procesie potomnym, i nie jest jasne, jak by to działało dla wbudowanego polecenia, który nie działa w procesie potomnym. Niewiele wbudowanych poleceń ma bezpośredni dostęp do środowiska, a ich interakcja ze zmiennymi powłoki jest czasami tajemna. Ale wymyśliłem kilka innych przykładów, które mogą być bardziej tym, czego szukasz:
foo=bar eval 'echo $foo'
wyświetli „pasek”, ponieważ ocena $foo
jest odroczona. Jest on obsługiwany przez eval
(wbudowane) polecenie, a nie przez początkowe polecenie parsowania powłoki. Lub utwórz plik tekstowy o nazwie (na przykład) showme.sh
. Umieść w nim echo $foo
(lub echo "$foo"
) polecenie i powiedz
foo=bar . showme.sh
Prawdopodobnie o tym mówi Twoja książka, gdy mówi: „… powłoka musi śledzić prawidłową kolejność rozwiązywania odwołań do zmiennych…”. W jakiś sposób powłoka uruchamia polecenia showme.sh
z foo
równą bar
, a następnie powraca do poprzednia wartość foo
(jeśli istnieje), gdy wraca do pierwotnego wejścia (terminala).