Eu sei que env
é um comando shell, ele pode ser usado para imprimir uma lista das variáveis de ambiente atuais. E, tanto quanto 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
?
shell
environment-variables
mcmxciv
fonte
fonte
env
não é um comando do shell, pois geralmente não é incorporado ao shell.declare -x
é o equivalente em um shell embutido.Respostas:
RANDOM
não é uma variável de ambiente. É uma variável de shell mantida por algumas conchas. Geralmente não é exportado por padrão. É por isso que ele não aparece na saída deenv
.Uma vez que foi usado pelo menos uma vez, ele iria aparecer na saída
set
, o que, por si só, lista as variáveis do shell (e funções) e seus valores na sessão shell atual. Esse comportamento é dependente do shell e usapdksh
no OpenBSD,RANDOM
seria listadoset
mesmo se não fosse usado anteriormente.O restante desta resposta diz respeito ao que se poderia esperar se
RANDOM
fosse exportado (ou seja, transformado em uma variável de ambiente).Exportando-o com
export RANDOM
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 o
pdksh
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
torna o acesso shell a sua internoget_random()
função para dar a variável um novo valor aleatório, mas o shell não atualiza a variável de ambienteRANDOM
. Este é um comportamento semelhante como com outros dinâmicasbash
variáveis, tais comoLINENO
,SECONDS
,BASHPID
etc.Para atualizar a variável de ambiente
RANDOM
embash
, você teria que atribuir-lhe o valor da variável de shellRANDOM
e re-exportá-lo:Não está claro para mim se isso teria o efeito colateral adicional de re-semear o gerador de números aleatórios
bash
ou não (mas um palpite fundamentado seria que não existe).fonte
RANDOM
algum valor antes de usá-lo? Eu sempre assumi que ele só era preenchido quando chamado.export RANDOM
oudeclare -p RANDOM
, ao que parece, por isso não tenho certeza se é qualquer uso que não existe antes de ser referenciada ...Nem todas as variáveis definidas em sua sessão do shell são variáveis de ambiente. "Variáveis de ambiente" refere-se apenas às variáveis que foram exportadas para o ambiente usando o
export
builtin. Oenv
comando imprime apenas essas variáveis de ambiente . Por exemplo:Se você deseja 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, portanto, para ver apenas variáveis, você pode usar:Por fim, a
RANDOM
variável é especial, pois somente recebe um valor quando você a referencia. Isso é mencionado no bash (1) :Portanto, mesmo que fosse uma variável de ambiente como você pensava, ela não teria sido mostrada,
env
pois não seria configurada até a primeira vez que você a chamou. É também por isso que não é mostrado emset
:fonte
set | grep RAN
. Eu não esperava isso. FWIW, acredito que não possa ser previsto pela documentação.A maioria dos shells terá várias outras variáveis definidas ou usadas pelo shell que não são exportadas para processos filho por padrão.
No Bash, existem alguns obviamente específicos do Bash:
Depois, existem outros padrões como
OPTIND
andOPTERR
(used bygetopts
), andPS2
,PS3
(the 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 seus status de exportação com
declare -p
. Os marcados com-x
são exportados, os que nãox
são. (Alguns terão outros sinalizadores comoi
para inteiro our
somente leitura.)No Zsh ou no 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
.fonte
Se você pesquisar no Google, os documentos declaram o seguinte:
Se você usar,
strace
poderá ver que a$RANDOM
"variável" é passada diretamente para os comandos como se fosse uma variável comum do shell ou uma variável de ambiente, mas é apenas uma função interna incorporada ao shell, o Bash, que está fazendo a expansão.vs. esta variável regular:
A variável não está sendo transmitida como referência.
Referências
fonte
$RANDOM
ou$SOMEVAR
através de um argumento de linha de comando, e não como uma variável de ambiente? Você precisaria deexport
ambos para passá-los pelo ambiente.strace
saída não parece capturar a função interna executada pelo shell. Nos dois casos, a variável já foi expandida na primeira linha dostrace
. Não entendo que diferença você está apontando. o que estou perdendo?$RANDOM
expansão é feita internamente no shell. É basicamente a confirmação de que o shell está determinando o valor e não passando uma referência a uma variável. O shell quando está expandindo a linha de comando para executar analisa$RANDOM
e passa o formulário expandido paraecho
.