Problem ponownie odwiedzony
Szczerze mówiąc, podręcznik jest niejasny w tej kwestii. Podręcznik GNU Bash mówi:
Środowisko dla każdego prostego polecenia lub funkcji [zwróć uwagę, że wyklucza to polecenia wbudowane] można tymczasowo rozszerzyć, dodając do niego przedrostek przypisanymi parametrami, jak opisano w sekcji Parametry powłoki. Te instrukcje przypisania wpływają tylko na środowisko widziane przez to polecenie.
Jeśli naprawdę przeanalizujesz zdanie, to mówi, że środowisko polecenia / funkcji jest zmodyfikowane, ale nie środowisko dla procesu nadrzędnego. Więc to zadziała:
$ TESTVAR=bbb env | fgrep TESTVAR
TESTVAR=bbb
ponieważ środowisko dla polecenia env zostało zmodyfikowane przed jego wykonaniem. Jednak to nie zadziała:
$ set -x; TESTVAR=bbb echo aaa $TESTVAR ccc
+ TESTVAR=bbb
+ echo aaa ccc
aaa ccc
z powodu tego, kiedy interpretacja parametrów jest wykonywana przez powłokę.
Kroki tłumacza
Inną częścią problemu jest to, że Bash definiuje następujące kroki dla swojego interpretera:
- Odczytuje swoje dane wejściowe z pliku (zobacz Skrypty powłoki), z łańcucha dostarczonego jako argument opcji wywołania -c (zobacz Wywoływanie Bash) lub z terminala użytkownika.
- Dzieli dane wejściowe na słowa i operatory, przestrzegając zasad cytowania opisanych w cytowaniu. Te żetony są oddzielone metaznakami. Rozwijanie aliasów jest wykonywane w tym kroku (zobacz Aliasy).
- Przetwarza tokeny na proste i złożone polecenia (zobacz Polecenia powłoki).
- Wykonuje różne rozszerzenia powłoki (zobacz Rozszerzenia powłoki), dzieląc rozwinięte tokeny na listy nazw plików (zobacz Rozszerzanie nazw plików) oraz polecenia i argumenty.
- Wykonuje wszelkie niezbędne przekierowania (zobacz Przekierowania) i usuwa operatory przekierowania i ich operandy z listy argumentów.
- Wykonuje polecenie (patrz Wykonywanie poleceń).
- Opcjonalnie czeka na zakończenie polecenia i zbiera jego status wyjścia (zobacz Status wyjścia).
To, co się tutaj dzieje, to fakt, że elementy wbudowane nie otrzymują własnego środowiska wykonawczego, więc nigdy nie widzą zmodyfikowanego środowiska. Ponadto, proste polecenia (np / bin / echo) mają otrzymać zmodyfikowany ennvironment (dlatego przykładem env pracował), ale rozszerzenie powłoki odbywa się w bieżącym środowisku w kroku # 4.
Innymi słowy, nie przekazujesz „aaa $ TESTVAR ccc” do / bin / echo; przekazujesz interpolowany ciąg (rozszerzony w bieżącym środowisku) do / bin / echo. W tym przypadku, ponieważ bieżące środowisko nie ma TESTVAR , po prostu przekazujesz komendę „aaa ccc”.
Podsumowanie
Dokumentacja mogłaby być dużo bardziej przejrzysta. Dobrze, że jest przepełnienie stosu!
Zobacz też
http://www.gnu.org/software/bash/manual/bashref.html#Command-Execution-Environment