Ich weiß env
, dass es sich um einen Shell-Befehl handelt, mit dem eine Liste der aktuellen Umgebungsvariablen gedruckt werden kann. Und soweit ich das verstehe, RANDOM
handelt es sich auch um eine Umgebungsvariable.
Warum ist env
die Ausgabe bei meinem Start unter Linux nicht enthalten RANDOM
?
shell
environment-variables
mcmxciv
quelle
quelle
env
ist kein Shell-Befehl, da er normalerweise nicht in die Shell integriert ist.declare -x
ist das Äquivalent in einer Shell eingebaut.Antworten:
RANDOM
ist keine Umgebungsvariable. Es ist eine Shell-Variable, die von einigen Shells verwaltet wird. Es wird in der Regel nicht standardmäßig exportiert. Aus diesem Grund wird es in der Ausgabe von nicht angezeigtenv
.Sobald es einmal zumindest verwendet wird worden, es würde in der Ausgabe erscheinen
set
, die, für sich allein, führt die Shell - Variablen (und Funktionen) und deren Werte in der aktuellen Shell - Sitzung. Dieses Verhalten ist abhängig von der Schale und mitpdksh
auf OpenBSD,RANDOM
würde von der Liste aufgeführt werden ,set
auch wenn nicht zuvor verwendet hat .Der Rest dieser Antwort bezieht sich darauf, was zu erwarten ist, wenn
RANDOM
es exportiert (dh in eine Umgebungsvariable umgewandelt) wurde.Wenn Sie es mit exportieren
export RANDOM
, wird es zu einer Umgebungsvariablen, die Verwendung ist jedoch stark eingeschränkt, da der Wert in einem untergeordneten Prozess "zufällig, aber statisch" ist (dh, es handelt sich um eine unveränderliche Zufallszahl). Das genaue Verhalten unterscheidet sich zwischen den Schalen.Ich verwende
pdksh
OpenBSD im folgenden Beispiel und erhalte bei jedemawk
Lauf einen neuen Zufallswert (aber jedes Mal den gleichen Wert innerhalb derselbenawk
Instanz). Mitbash
würde ich in allen Aufrufen von genau den gleichen Zufallswert erhaltenawk
.In würde
bash
der exportierte Wert vonRANDOM
statisch bleiben, unabhängig von der VerwendungRANDOM
in der Shell (wobei jede Verwendung von$RANDOM
immer noch einen neuen Wert ergeben würde).Dies liegt daran, dass bei jedem Verweis auf die Shell-Variable
RANDOM
inbash
die Shell auf ihre interneget_random()
Funktion zugegriffen wird, um der Variablen einen neuen Zufallswert zu geben, die Shell jedoch die Umgebungsvariable nicht aktualisiertRANDOM
. Dies ist ähnlich im Verhalten wie bei anderen dynamischenbash
Variablen, wieLINENO
,SECONDS
,BASHPID
usw.Um die Umgebungsvariable
RANDOM
in zu aktualisierenbash
, müssten Sie ihr den Wert der Shell-Variablen zuweisenRANDOM
und sie erneut exportieren:Es ist mir unklar, ob dies den zusätzlichen Nebeneffekt haben würde, den Zufallszahlengenerator wieder einzuspielen
bash
oder nicht (aber eine fundierte Vermutung wäre, dass dies nicht der Fall ist).quelle
RANDOM
noch ein Wert bevor Sie es verwenden? Ich war immer davon ausgegangen, dass es nur bei einem Anruf besiedelt war.export RANDOM
oder tundeclare -p RANDOM
, scheint es, so bin ich nicht sicher, ob es irgendeine Verwendung ist, dass es nicht existiert, bevor verwiesen wird ...Nicht alle in Ihrer Shell-Sitzung festgelegten Variablen sind Umgebungsvariablen. "Umgebungsvariablen" bezieht sich nur auf die Variablen, die mit der
export
integrierten Funktion in die Umgebung exportiert wurden. Derenv
Befehl druckt nur solche Umgebungsvariablen . Beispielsweise:Wenn Sie alle Variablen in Ihrer Sitzung anzeigen möchten, unabhängig davon, ob sie exportiert wurden, können Sie Folgendes verwenden
set
:Das
set
Builtin gibt auch Funktionen zurück. Um also nur Variablen anzuzeigen, können Sie Folgendes verwenden:Schließlich ist die
RANDOM
Variable insofern besonders, als ihr nur dann ein Wert zugewiesen wird, wenn Sie darauf verweisen. Dies wird in bash (1) erwähnt :Selbst wenn es eine Umgebungsvariable wäre, wie Sie dachten, würde sie nicht angezeigt werden,
env
da sie erst beim ersten Aufruf festgelegt wird. Das ist auch der Grund, warum es nicht gezeigt wird inset
:quelle
set | grep RAN
. Ich hätte es nicht erwartet. FWIW, ich glaube, dass die Dokumentation dies nicht vorhersagen kann.In den meisten Shells werden eine Reihe anderer Variablen festgelegt oder von der Shell verwendet, die standardmäßig nicht in untergeordnete Prozesse exportiert werden.
In Bash gibt es einige offensichtlich Bash-spezifische:
Dann gibt es mehr Standard diejenigen wie
OPTIND
undOPTERR
(verwendet vongetopts
) undPS2
,PS3
(die sekundären Prompts) und sogar eine andere „magische“ Variable:SECONDS
(zeigt die Zeit in Sekunden , da die Shell gestartet)In Bash sehen Sie alle Variablen und deren Exportstatus mit
declare -p
. Die mit gekennzeichneten-x
werden exportiert, die ohnex
nicht. (Einige haben andere Flags, wiei
zum Beispiel für Ganzzahlen oderr
für Nur-Lese- Flags .)In Zsh oder ksh93 können Sie verwenden
typeset -p
, obwohl Zsh die exportierten Variablen durch Änderntypeset
inexport
in der Ausgabe markiert , anstatt Flags zu verwenden.export
Alleine würde auch alle exportierten Variablen anzeigen, aber das ist ungefähr dasselbe Ergebnis, das Sie durch Ausführen erhaltenenv
.quelle
Wenn Sie dafür googeln, geben die Dokumente Folgendes an:
Wenn Sie verwenden
strace
, können Sie sehen, dass die$RANDOM
"Variable" direkt an Befehle übergeben wird, als wäre es eine gewöhnliche Shell-Variable oder eine Umgebungsvariable, aber es ist nur eine interne Funktion, die in die Shell eingebaut ist, Bash, die die Erweiterung vornimmt.gegen diese reguläre Variable:
Die Variable wird nicht als Referenz übergeben.
Verweise
quelle
$RANDOM
oder$SOMEVAR
über ein Befehlszeilenargument und nicht als Umgebungsvariable? Sie müsstenexport
beide durch die Umgebung leiten.strace
Ausgabe scheint die von der Shell ausgeführte interne Funktion nicht zu erfassen. In beiden Fällen wurde die Variable bereits in der ersten Zeile der erweitertstrace
. Ich verstehe nicht, auf welchen Unterschied Sie hinweisen. Was vermisse ich?$RANDOM
Erweiterung intern in der Shell erfolgt. Es ist im Grunde eine Bestätigung, dass die Shell den Wert bestimmt und keinen Verweis auf eine Variable übergibt. Die Shell, wenn sie die Befehlszeile zum Ausführen von Parses erweitert$RANDOM
und das erweiterte Formular an übergibtecho
.