Eu sei que env
é um comando shell, ele pode ser usado para imprimir uma lista das variáveis de ambiente atuais. E até onde eu entendo, RANDOM
também é uma variável de ambiente.
Então, por que, quando inicio env
no Linux, a saída não inclui RANDOM
?
RANDOM
não é uma variável de ambiente. É uma variável de shell mantida por alguns shells. Geralmente não é exportado por padrão. É por isso que ele não aparece na saída doenv
.Uma vez que tenha sido usado pelo menos uma vez, ele aparecerá na saída de
set
, que, por si só, lista as variáveis do shell (e funções) e seus valores na sessão atual do shell. Este comportamento é dependente do shell e usandopdksh
no OpenBSD,RANDOM
seria listado porset
mesmo que não tenha sido usado anteriormente.O restante desta resposta diz respeito ao que poderia acontecer se
RANDOM
fosse exportado (ou seja, transformado em uma variável de ambiente).Exportá-lo com
export RANDOM
o tornaria uma variável de ambiente, mas seu uso seria severamente limitado, pois seu valor em um processo filho seria "aleatório, mas estático" (o que significa que seria um número aleatório imutável). O comportamento exato difere entre as conchas.Estou usando
pdksh
no OpenBSD no exemplo abaixo e recebo um novo valor aleatório em cadaawk
execução (mas o mesmo valor todas as vezes na mesmaawk
instância). Usandobash
, eu obteria exatamente o mesmo valor aleatório em todas as invocações deawk
.Em
bash
, o valor exportado deRANDOM
permaneceria estático independentemente do uso deRANDOM
no shell (onde cada uso de$RANDOM
ainda daria um novo valor).Isso ocorre porque cada referência à variável shell
RANDOM
embash
faz com que o shell acesse sua função internaget_random()
para dar à variável um novo valor aleatório, mas o shell não atualiza a variável de ambienteRANDOM
. Isso é semelhante em comportamento a outrasbash
variáveis dinâmicas, comoLINENO
,SECONDS
,BASHPID
etc.Para atualizar a variável de ambiente
RANDOM
embash
, você teria que atribuir a ela o valor da variável shellRANDOM
e exportá-la novamente:Não está claro para mim se isso teria o efeito colateral adicional de re-semeadura do gerador de números aleatórios
bash
ou não (mas um palpite seria que não).Nem todas as variáveis definidas em sua sessão de shell são variáveis de ambiente. "Variáveis de ambiente" referem-se apenas às variáveis que foram exportadas para o ambiente usando o
export
built-in. Oenv
comando imprime apenas essas variáveis de ambiente . Por exemplo:Se você quiser ver todas as variáveis definidas em sua sessão, independentemente de terem sido exportadas, você pode usar
set
:O
set
builtin também retorna funções, então para ver apenas variáveis, você pode usar:Finalmente, a
RANDOM
variável é especial porque só recebe um valor quando você a referencia. Isso é mencionado em bash(1) :Portanto, mesmo se fosse uma variável de ambiente como você pensou, ela não teria sido mostrada,
env
pois não seria definida até a primeira vez que você a chamasse. É também por isso que não é mostrado emset
:A maioria dos shells terá várias outras variáveis definidas ou usadas pelo shell que não são exportadas para processos filhos por padrão.
No Bash, existem alguns obviamente específicos do Bash:
Depois, há mais padrões como
OPTIND
andOPTERR
(usado porgetopts
), ePS2
,PS3
(os prompts secundários) e até outra variável "mágica":SECONDS
(mostra o tempo em segundos desde que o shell foi iniciado)No Bash, você pode ver todas as variáveis e seu status de exportação com
declare -p
. Os marcados com-x
são exportados, os semx
não são. (Alguns terão outros sinalizadores comoi
para inteiro our
somente leitura.)No Zsh ou ksh93, você pode usar
typeset -p
, embora o Zsh marque as variáveis exportadas alterandotypeset
paraexport
na saída, em vez de usar sinalizadores.export
por si só também mostraria todas as variáveis exportadas, mas esse é o mesmo resultado que você obtém executandoenv
.Se você pesquisar no Google para isso, os documentos afirmam o seguinte:
Se você usar
strace
, verá que a$RANDOM
"variável" é passada diretamente aos comandos como se fosse qualquer variável comum do shell ou uma variável de ambiente, mas é apenas uma função interna incorporada ao shell, Bash, que está fazendo a expansão.vs. esta variável regular:
A variável não está sendo passada como referência.
Referências