Utworzyłem zmienną środowiskową w jednym oknie terminala i próbowałem powtórzyć ją w innym oknie terminala. To nic nie wyświetlało.
$TEST=hello
Następnie wyeksportowałem to i spróbowałem ponownie echo
w innym oknie terminala . wynik był taki sam jak poprzednio.
export TEST
ale jeśli wykonam ten sam kod przy logowaniu (dołączę kod do ~/.profile
file) można używać w dowolnym oknie terminala. Co tu się dzieje? Jaka jest różnica między wykonaniem kodu w terminalu a wykonaniem tego samego przy logowaniu?
Odpowiedź
export
sprawia, że zmienna jest czymś, co zostanie uwzględnione w potomnych środowiskach procesów. Nie ma wpływu na inne już istniejące środowiska. Generalnie nie ma sposobu na ustawienie zmiennej w jednym terminalu i automatyczne pojawienie się jej w innym. Środowisko jest ustanawiane osobno dla każdego procesu.
Dodanie go do .profile
sprawia, że środowisko będzie skonfigurowane tak, aby zawierało tę nową zmienną za każdym razem, gdy się logujesz. Więc nie jest ona eksportowana z jednej powłoki do drugiej, ale zamiast tego instruuje nową powłokę, aby zawierała podczas konfigurowania środowiska początkowego.
Odpowiedź
Każdy proces ma kilka atrybutów, które może ustawić indywidualnie i niezależnie od inne procesy. Przykładami są limity zasobów, umask, bieżący katalog, zmienne środowiskowe i kilka innych. Podczas tworzenia procesu (za pomocą wywołania systemowego fork()
) dziecko dziedziczy te atrybuty po rodzicu. Następnie proces potomny może dowolnie ustawić te atrybuty. (Obowiązują pewne ograniczenia, proces nie może zwiększyć sztywnych limitów zasobów ani zmienić swojego bieżącego katalogu na katalog, do którego nie ma uprawnień wykonywania).
Tylko kilka programów modyfikuje swoje zmienne środowiskowe, większość z nich nie przejmuje się . Przypuśćmy drugi przypadek. Więc jeśli proces potomny tworzy sobie dalsze dzieci, wtedy te procesy będą miały te same zmienne środowiskowe co dziadek. I tak dalej.
Otóż, powłoka ma wiele zmiennych, które można wyświetlić za pomocą set
(w powłokach typu Bourne Shell, nie wiem o powłoce C). Te zmienne nie są zmiennymi środowiskowymi, chyba że są export
ed. Zmienne środowiskowe można wyświetlać za pomocą env
. Jeśli uruchomisz program z wiersza poleceń powłoki, program odziedziczy zmienne środowiskowe z powłoki. Podobnie w przypadku programu uruchomionego z skrypt powłoki.
Dlatego po zalogowaniu się istnieje powłoka, która odczytuje dane profilu (np. ~/.profile
) i dziedziczy je praktycznie wszystkim dzieciom, wnukom i tak dalej. W ten sposób ustawienia zmiennych środowiskowych spływają z powłoki logowania lub skryptu logowania do wszystkich innych programów uruchomionych podczas sesji logowania.
Utworzyłem zmienną środowiskową w jedno okno terminala i próbowałem powtórzyć je w innym oknie terminala. To nic nie wyświetliło.
Zgodnie z powyższym wyjaśnieniem, jest to oczekiwany wynik. Zmiany w środowisku procesu dotyczą tylko elementów podrzędnych tego procesu, które są tworzone odtąd, a nie istniejących.
$TEST=hello
To i tak raczej nie zadziała, chyba że rozwijanie zmiennych jest wyłączone lub $TEST
ma już odpowiednia wartość. Jeśli chcesz przypisać hello
do zmiennej TEST
, musisz powiedzieć TEST=hello
(uwaga : nie $
).
Następnie wyeksportowałem go i ponownie spróbowałem
echo
w innym oknie terminala. wynik był taki sam jak poprzednio.
Po raz kolejny jest to oczekiwany wynik.
ale jeśli wykonam ten sam kod przy logowaniu (dołączając kod do pliku
~/.profile
), zmienne mogą być użyte w dowolnym oknie terminala.
Dzieje się tak, ponieważ powłoka w terminalu jest potomkiem powłoki, która odczytuje ustawienia środowiska z ~/.profile
i dziedziczy te ustawienia.