Je sais que env
c'est une commande shell, elle peut être utilisée pour imprimer une liste des variables d'environnement actuelles. Et pour autant que je comprends, RANDOM
est également une variable d'environnement.
Alors pourquoi, lorsque je lance env
sur Linux, la sortie ne comprend-elle pas RANDOM
?
shell
environment-variables
mcmxciv
la source
la source
env
n'est pas une commande shell car elle n'est généralement pas intégrée au shell.declare -x
est l'équivalent dans un shell intégré.Réponses:
RANDOM
n'est pas une variable d'environnement. C'est une variable shell maintenue par certains shells. Il n'est généralement pas exporté par défaut. C'est pourquoi il n'apparaît pas dans la sortie deenv
.Une fois qu'il a été utilisé au moins une fois, il serait affiché dans la sortie
set
, qui, par lui - même, énumère les variables shell (et fonctions) et leurs valeurs dans la session shell en cours. Ce comportement dépend du shell et l'utilisationpdksh
d'OpenBSDRANDOM
serait répertoriéset
même s'il n'était pas utilisé auparavant.Le reste de cette réponse concerne ce qui pourrait se produire s'il
RANDOM
était exporté (c'est-à-dire transformé en variable d'environnement).L'exporter avec en
export RANDOM
ferait une variable d'environnement mais son utilisation serait sévèrement limitée car sa valeur dans un processus enfant serait "aléatoire mais statique" (ce qui signifie que ce serait un nombre aléatoire immuable). Le comportement exact diffère entre les coques.J'utilise
pdksh
sur OpenBSD dans l'exemple ci-dessous et j'obtiens une nouvelle valeur aléatoire à chaqueawk
exécution (mais la même valeur à chaque fois dans la mêmeawk
instance). En utilisantbash
, j'obtiendrais exactement la même valeur aléatoire dans toutes les invocations deawk
.Dans
bash
, la valeur exportée deRANDOM
resterait statique quelle que soit l'utilisation deRANDOM
dans le shell (où chaque utilisation de$RANDOM
donnerait toujours une nouvelle valeur).En effet, chaque référence à la variable shell
RANDOM
dansbash
le shell accède à saget_random()
fonction interne pour donner à la variable une nouvelle valeur aléatoire, mais le shell ne met pas à jour la variable d'environnementRANDOM
. Ceci est similaire dans le comportement comme avec d' autres dynamiquesbash
variables, telles queLINENO
,SECONDS
,BASHPID
etc.Pour mettre à jour la variable d'environnement
RANDOM
dansbash
, vous devez lui affecter la valeur de la variable shellRANDOM
et la réexporter:Il n'est pas clair pour moi si cela aurait l'effet secondaire supplémentaire de réensemencer le générateur de nombres aléatoires
bash
ou non (mais une supposition éclairée serait que ce n'est pas le cas).la source
RANDOM
- il même une valeur avant de l'utiliser? J'avais toujours supposé qu'il n'était peuplé qu'au moment de l'appel.export RANDOM
oudeclare -p RANDOM
, il apparaît, donc je ne suis pas sûr si c'est utile qu'il n'existe pas avant d'être référencé ...Toutes les variables définies dans votre session shell ne sont pas des variables d'environnement. "Variables d'environnement" se réfère uniquement aux variables qui ont été exportées vers l'environnement à l'aide de la fonction
export
intégrée. Laenv
commande imprime uniquement ces variables d' environnement . Par exemple:Si vous souhaitez voir toutes les variables définies dans votre session, qu'elles aient été exportées ou non, vous pouvez utiliser
set
:La fonction
set
intégrée renvoie également des fonctions, donc pour voir uniquement les variables, vous pouvez utiliser:Enfin, la
RANDOM
variable a la particularité de ne recevoir une valeur que lorsque vous la référencez. Ceci est mentionné dans bash (1) :Donc, même s'il s'agissait d'une variable d'environnement comme vous le pensiez, elle n'aurait pas été affichée
env
car elle ne serait définie que la première fois que vous l'avez appelée. C'est aussi pourquoi il n'apparaît pas dansset
:la source
set | grep RAN
. Je ne m'y attendais pas. FWIW, je crois que cela ne peut pas être prédit par la documentation.La plupart des shells auront un certain nombre d'autres variables définies ou utilisées par le shell qui ne sont pas exportées par défaut vers les processus enfants.
Dans Bash, il y en a de toute évidence spécifiques à Bash:
Ensuite, il y a plus de standards comme
OPTIND
etOPTERR
(utilisé pargetopts
), etPS2
,PS3
(les invites secondaires) et même une autre variable "magique":SECONDS
(affiche le temps en secondes depuis le démarrage du shell)Dans Bash, vous pouvez voir toutes les variables et leur statut d'exportation avec
declare -p
. Ceux marqués d'un-x
sont exportés, ceux qui ne lex
sont pas. (Certains auront d'autres indicateurs commei
pour entier our
en lecture seule.)Dans Zsh ou ksh93, vous pouvez utiliser
typeset -p
, bien que Zsh marque les variables exportées en changeanttypeset
enexport
dans la sortie, au lieu d'utiliser des indicateurs.export
à lui seul afficherait également toutes les variables exportées, mais c'est à peu près le même résultat que vous obtenez en exécutantenv
.la source
Si vous utilisez Google pour cela, les documents indiquent ce qui suit:
Si vous utilisez,
strace
vous pouvez voir que la$RANDOM
"variable" est transmise directement aux commandes comme s'il s'agissait d'une variable shell ordinaire ou d'une variable d'environnement, mais c'est juste une fonction interne qui est intégrée dans le shell, Bash, qui fait l'expansion.par rapport à cette variable régulière:
La variable n'est pas transmise comme référence.
Les références
la source
$RANDOM
ou$SOMEVAR
via un argument de ligne de commande, et non pas comme une variable d'environnement? Vous auriez besoin desexport
deux pour les faire passer dans l'environnement.strace
sortie ne semble pas intercepter la fonction interne exécutée par le shell. Dans les deux cas, la variable a déjà été développée dans la première ligne dustrace
. Je ne comprends pas quelle différence vous signalez. Qu'est-ce que je rate?$RANDOM
expansion se fait en interne au shell. C'est essentiellement la confirmation que le shell détermine la valeur et ne transmet pas de référence à une variable. Le shell lorsqu'il étend la ligne de commande pour exécuter des analyses$RANDOM
et passe le formulaire développé àecho
.