Wiem, że env
to polecenie powłoki, może być użyte do wydrukowania listy aktualnych zmiennych środowiskowych. O ile rozumiem, RANDOM
jest to również zmienna środowiskowa.
Dlaczego więc, kiedy uruchamiam env
w systemie Linux, dane wyjściowe nie obejmują RANDOM
?
shell
environment-variables
mcmxciv
źródło
źródło
env
nie jest poleceniem powłoki, ponieważ zwykle nie jest wbudowane w powłokę.declare -x
jest odpowiednikiem wbudowanej powłoki.Odpowiedzi:
RANDOM
nie jest zmienną środowiskową. Jest to zmienna powłoki obsługiwana przez niektóre powłoki. Zwykle nie jest eksportowany domyślnie. Dlatego nie pojawia się na wyjściuenv
.Raz to było wykorzystywane co najmniej raz, by pokazać się na wyjściu
set
, który sam w sobie, listy zmienne powłoki (i funkcje) i ich wartości w bieżącej sesji powłoki. To zachowanie zależy od powłoki i użyciapdksh
na OpenBSD,RANDOM
byłoby wymienione na liście,set
nawet jeśli nie było wcześniej używane.Pozostała część odpowiedzi dotyczy tego, czego można się było spodziewać, gdyby
RANDOM
został wyeksportowany (tj. Przekształcony w zmienną środowiskową).Wyeksportowanie go
export RANDOM
spowoduje, że będzie zmienną środowiskową, ale jego użycie byłoby poważnie ograniczone, ponieważ jego wartość w procesie potomnym byłaby „losowa, ale statyczna” (co oznacza, że byłaby niezmienną liczbą losową). Dokładne zachowanie różni się w zależności od powłoki.Korzystam
pdksh
z OpenBSD w poniższym przykładzie i otrzymuję nową losową wartość przy każdymawk
uruchomieniu (ale tę samą wartość za każdym razem w tej samejawk
instancji). Używającbash
, uzyskałbym dokładnie tę samą losową wartość we wszystkich wywołaniachawk
.W
bash
, wyeksportowana wartośćRANDOM
pozostałaby statyczna bez względu na użycieRANDOM
w powłoce (gdzie każde użycie$RANDOM
wciąż dawałoby nową wartość).To dlatego, że każde odwołanie do zmiennej powłoki
RANDOM
wbash
sprawia, że dostęp do powłoki jej wewnętrznaget_random()
funkcja dać zmiennej nową wartość losową, ale powłoka nie aktualizuje zmienną środowiskowąRANDOM
. Jest to podobne do zachowania jak w przypadku innych dynamicznychbash
zmiennych, takich jakLINENO
,SECONDS
,BASHPID
itpAby zaktualizować zmienną środowiskową
RANDOM
wbash
, trzeba by przypisać mu wartość zmiennej powłokiRANDOM
i reeksportu go:Nie jest dla mnie jasne, czy miałoby to dodatkowy efekt uboczny ponownego uruchomienia generatora liczb losowych,
bash
czy też nie (ale zgadywano by, że tak nie jest).źródło
RANDOM
ogóle ma jakąś wartość przed użyciem? Zawsze zakładałem, że jest wypełniony tylko na wezwanie.export RANDOM
lubdeclare -p RANDOM
wydaje się, więc nie jestem pewien, czy to pożytek, że nie istnieje przed odniesieniem ...Nie wszystkie zmienne ustawione w sesji powłoki są zmiennymi środowiskowymi. „Zmienne środowiskowe” odnoszą się tylko do tych zmiennych, które zostały wyeksportowane do środowiska przy użyciu
export
wbudowanego.env
Komenda drukuje tylko takie środowisko zmienne. Na przykład:Jeśli chcesz zobaczyć wszystkie zmienne ustawione w sesji, niezależnie od tego, czy zostały wyeksportowane, możesz użyć
set
:set
Wbudowane zwraca również funkcje, tak aby widzieć tylko zmienne, można użyć:Wreszcie,
RANDOM
zmienna jest wyjątkowa, ponieważ przypisuje się jej wartość tylko wtedy, gdy się do niej odwołujesz. Zostało to wspomniane w bash (1) :Więc nawet gdyby była to zmienna środowiskowa, jak się spodziewałeś, nie zostałaby pokazana,
env
ponieważ nie zostałaby ustawiona do pierwszego wywołania. Dlatego też nie jest pokazany wset
:źródło
set | grep RAN
. Nie spodziewałbym się tego. FWIW, uważam, że nie można tego przewidzieć w dokumentacji.Większość powłok ma ustawione lub używane przez powłokę wiele innych zmiennych, które domyślnie nie są eksportowane do procesów potomnych.
W Bash istnieją pewne, oczywiście, specyficzne dla Bash:
Potem jest bardziej standardowych jak
OPTIND
iOPTERR
(używany przezgetopts
) iPS2
,PS3
(wtórne monity), a nawet inny „magia” zmienna:SECONDS
(pokazuje czas w sekundach od uruchomienia powłoki)W Bash możesz zobaczyć wszystkie zmienne i ich status eksportu za pomocą
declare -p
. Te oznaczone-x
są eksportowane, a te bezx
. (Niektóre będą miały inne flagi, takie jaki
dla liczb całkowitych lub tylkor
do odczytu).W zsh lub ksh93 można użyć
typeset -p
, choć wskazuje na zsh wyeksportowanych zmiennych zmieniająctypeset
sięexport
w produkcji, zamiast używania flagi.export
sam w sobie pokazywałby również wszystkie wyeksportowane zmienne, ale jest to mniej więcej taki sam wynik, jaki można uzyskać, uruchamiającenv
.źródło
Jeśli korzystasz z wyszukiwarki Google, dokumenty zawierają następujące informacje:
Jeśli go użyjesz
strace
, zobaczysz, że$RANDOM
„zmienna” jest przekazywana bezpośrednio do poleceń, tak jakby to była zwykła zmienna powłoki lub zmienna środowiskowa, ale to tylko funkcja wewnętrzna wbudowana w powłokę, Bash, która dokonuje rozszerzenia.vs. ta zmienna regularna:
Zmienna nie jest przekazywana jako odniesienie.
Referencje
źródło
$RANDOM
lub$SOMEVAR
przez argument wiersza poleceń, a nie jako zmienna środowiskowa? Musiszexport
oba, aby przejść przez środowisko.strace
dane wyjściowe nie wychwytują funkcji wewnętrznej uruchamianej przez powłokę. W obu przypadkach zmienna została już rozwinięta w pierwszym wierszustrace
. Nie rozumiem, na którą różnicę wskazujesz. czego mi brakuje?$RANDOM
rozszerzenie jest wykonywane wewnętrznie w powłoce. Jest to w zasadzie potwierdzenie, że powłoka określa wartość, a nie przekazanie odwołania do zmiennej. Powłoka, gdy rozwija linię poleceń w celu wykonania parsowania$RANDOM
i przekazuje rozwiniętą formę doecho
.