Zmienna powłoki a zmienna środowiskowa, który jest preferowany, jeśli oba mają tę samą nazwę?

10

Wpisując następujące polecenia w Bash:

env | grep USER

i

set | grep USER

daje oba razy tę samą nazwę użytkownika.

Skąd mam wiedzieć, na przykład podczas pisania, echo $USERczy powłoka lub zmienna środowiskowa została wyświetlona?

rekin
źródło

Odpowiedzi:

14

W przypadku powłok kompatybilnych z POSIX (w tym Bash) standard mówi:

2.5.3 Zmienne otoczki
Zmienne należy inicjować ze środowiska [...] Jeżeli zmienna jest inicjowana ze środowiska, należy ją natychmiast oznaczyć do eksportu; zobacz specjalne wbudowane eksportowanie. Nowe zmienne można zdefiniować i zainicjować za pomocą przypisań zmiennych, [itd.]

Oraz o export:

export name[=word]...
Powłoka przekaże atrybut eksportu do zmiennych odpowiadających podanym nazwom, co spowoduje, że znajdą się one w środowisku później wykonywanych poleceń.

Z punktu widzenia powłoki istnieją tylko zmienne. Niektóre z nich mogły pochodzić ze środowiska podczas uruchamiania powłoki, a niektóre z nich mogą być eksportowane do środowiska procesów uruchamianych przez powłokę.

(„Środowisko” to tak naprawdę tylko kilka ciągów znaków przekazywanych do procesu podczas jego uruchamiania. Gdy proces jest uruchomiony, może robić z tym, co chce, używać go, ignorować, zastępować. I to, co proces przechodzi dalej kiedy uruchamianie innych procesów może być jeszcze inną rzeczą, choć oczywiście zwykle po prostu ponownie przekazujemy wszystkie zmienne środowiskowe).


Jeśli używasz powłoki innej niż POSIX, na przykład cshrzeczy mogą wyglądać inaczej:

$ csh
% echo $foo
foo: Undefined variable.
% setenv foo bar
% echo $foo
bar
% set foo=asdf
% echo $foo
asdf
% env |grep foo
foo=bar
% exit
ilkkachu
źródło
1
Zauważ, że powłoka Bourne'a, podobnie jak csh, inicjuje zmienne powłoki ze zmiennych środowiskowych. Ale modyfikowanie zmiennych powłoki nie wpływa na odpowiednią zmienną środowiskową, chyba że zostaną wyeksportowane. To coś zostało zepsute przez powłokę Korna (i określone przez POSIX). Dlatego powinieneś uważać na nazwę zmiennych powłoki, których używasz teraz, aby upewnić się, że nie modyfikujesz zmiennych env, które mogłyby mieć wpływ na polecenia uruchamiane w skrypcie.
Stéphane Chazelas
4

Są to jedna i ta sama zmienna. W powłoce, w przeciwieństwie do większości innych języków programowania, zmienne środowiskowe i zmienne powłoki mają tę samą przestrzeń nazw. W powłoce zmienna środowiskowa to zmienna powłoki, która została wyeksportowana export.

Zobacz na przykład moją odpowiedź na poprzednie pytanie „ Jaka jest różnica w użyciu między zmiennymi powłoki a zmiennymi środowiskowymi?

Kusalananda
źródło
jeszcze raz przeczytam twoje wyjaśnienie, ale najpierw muszę się czegoś nauczyć, zanim zrozumiem twoją odpowiedź.
sharkant
@sharkant Nie martw się wcale. Jeśli coś mylę, po prostu powiedz mi, a postaram się wyjaśnić. Odpowiedź ilkkachu też jest dobra.
Kusalananda
nie, nie sądzę, masz dobry styl wyjaśnienia, tylko mój brak wiedzy nie może ich jeszcze pielęgnować.
rekinant
2

Zmienna powłoki może być używana tylko do bieżącej powłoki, nie można jej używać w całym systemie. Z drugiej strony Zmienna środowiskowa może być stosowana w całym systemie. Zgodnie z konwencją zmienne powłoki są pisane małymi literami, a zmienne środowiskowe pisane są wielkimi literami. Możesz ustawić zmienną powłoki jako zmienną środowiskową, wystarczy ją wyeksportować.

Nazmul Ahmed Noyon
źródło