AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 453547
Accepted
mcmxciv
mcmxciv
Asked: 2018-07-06 00:22:35 +0800 CST2018-07-06 00:22:35 +0800 CST 2018-07-06 00:22:35 +0800 CST

Por que $ RANDOM não está incluído na saída de 'env'?

  • 772

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, RANDOMtambém é uma variável de ambiente.

Então, por que, quando inicio envno Linux, a saída não inclui RANDOM?

environment-variables shell
  • 4 4 respostas
  • 5157 Views

4 respostas

  • Voted
  1. Best Answer
    Kusalananda
    2018-07-06T00:24:50+08:002018-07-06T00:24:50+08:00

    RANDOMnã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 do env.

    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 usando pdkshno OpenBSD, RANDOMseria listado por setmesmo que não tenha sido usado anteriormente.


    O restante desta resposta diz respeito ao que poderia acontecer se RANDOMfosse exportado (ou seja, transformado em uma variável de ambiente).

    Exportá-lo com export RANDOMo 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 pdkshno OpenBSD no exemplo abaixo e recebo um novo valor aleatório em cada awkexecução (mas o mesmo valor todas as vezes na mesma awkinstância). Usando bash, eu obteria exatamente o mesmo valor aleatório em todas as invocações de awk.

    $ awk 'BEGIN { print ENVIRON["RANDOM"], ENVIRON["RANDOM"] }'
    25444 25444
    
    $ awk 'BEGIN { print ENVIRON["RANDOM"], ENVIRON["RANDOM"] }'
    30906 30906
    

    Em bash, o valor exportado de RANDOMpermaneceria estático independentemente do uso de RANDOMno shell (onde cada uso de $RANDOMainda daria um novo valor).

    Isso ocorre porque cada referência à variável shell RANDOM em bashfaz com que o shell acesse sua função interna get_random()para dar à variável um novo valor aleatório, mas o shell não atualiza a variável de ambiente RANDOM . Isso é semelhante em comportamento a outras bashvariáveis ​​dinâmicas, como LINENO, SECONDS, BASHPIDetc.

    Para atualizar a variável de ambiente RANDOMem bash, você teria que atribuir a ela o valor da variável shell RANDOM e exportá-la novamente:

    export RANDOM="$RANDOM"
    

    Não está claro para mim se isso teria o efeito colateral adicional de re-semeadura do gerador de números aleatórios bashou não (mas um palpite seria que não).

    • 43
  2. terdon
    2018-07-06T00:44:40+08:002018-07-06T00:44:40+08:00

    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 exportbuilt-in. O envcomando imprime apenas essas variáveis ​​de ambiente . Por exemplo:

    $ foo="bar"
    $ env | grep foo ## returns nothing
    $ export foo
    $ env | grep foo ## now, env will print it
    foo=bar
    

    Se você quiser ver todas as variáveis ​​definidas em sua sessão, independentemente de terem sido exportadas, você pode usar set:

    $ set | grep foo=
    foo=bar
    

    O setbuiltin também retorna funções, então para ver apenas variáveis, você pode usar:

    set | grep  '^[^[:space:]]*='
    

    Finalmente, a RANDOMvariável é especial porque só recebe um valor quando você a referencia. Isso é mencionado em bash(1) :

    RANDOM

      Cada vez que este parâmetro é referenciado, um número inteiro aleatório entre 0 e 32767 é gerado. A sequência de números aleatórios pode ser inicializada atribuindo um valor a RANDOM. Se RANDOMnão estiver definido, ele perde suas propriedades especiais, mesmo se for redefinido posteriormente.

    Portanto, mesmo se fosse uma variável de ambiente como você pensou, ela não teria sido mostrada, envpois não seria definida até a primeira vez que você a chamasse. É também por isso que não é mostrado em set:

    $ set | grep RAN   ## returns nothing, RANDOM is unset
    $ echo "$RANDOM"   ## this will assign a value to RANDOM
    1234
    $ set | grep RAN   ## so now it will also appear in the output of set 
    RANDOM=1234
    
    • 16
  3. ilkkachu
    2018-07-06T01:09:28+08:002018-07-06T01:09:28+08:00

    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:

    $ echo "${!BASH*}"
    BASH BASHOPTS BASHPID BASH_ALIASES BASH_ARGC BASH_ARGV BASH_CMDS BASH_COMMAND BASH_LINENO BASH_SOURCE BASH_SUBSHELL BASH_VERSINFO BASH_VERSION
    $ echo $BASH_VERSION
    4.4.12(1)-release
    $ env|grep -c BASH
    0
    

    Depois, há mais padrões como OPTINDand OPTERR(usado por getopts), e PS2, 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 -xsão exportados, os sem xnão são. (Alguns terão outros sinalizadores como ipara inteiro ou rsomente leitura.)

    No Zsh ou ksh93, você pode usar typeset -p, embora o Zsh marque as variáveis ​​exportadas alterando typesetpara exportna saída, em vez de usar sinalizadores. exportpor si só também mostraria todas as variáveis ​​exportadas, mas esse é o mesmo resultado que você obtém executando env.

    • 4
  4. slm
    2018-07-06T00:44:39+08:002018-07-06T00:44:39+08:00

    Se você pesquisar no Google para isso, os documentos afirmam o seguinte:

    $RANDOMé uma função Bash interna (não uma constante) que retorna um inteiro pseudoaleatório [1] no intervalo de 0 a 32767. Ela não deve ser usada para gerar uma chave de criptografia.

    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.

    $ strace -t echo "random value: $RANDOM"
    04:37:58 execve("/bin/echo", ["echo", "random value: 30795"], [/* 27 vars */]) = 0
    04:37:58 brk(NULL)                      = 0x19c1000
    04:37:58 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9841351000
    ...
    

    vs. esta variável regular:

    $ strace -t echo "random value: $SOMEVAR"
    04:40:19 execve("/bin/echo", ["echo", "random value: helloworld"], [/* 27 vars */]) = 0
    04:40:19 brk(NULL)                      = 0x154b000
    04:40:19 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f659d2eb000
    ...
    

    A variável não está sendo passada como referência.

    Referências

    • $RANDOM: gera um inteiro aleatório
    • 2

relate perguntas

  • Como funciona este comando? mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc -l 1234 > /tmp/f

  • FreeBSD's sh: funções de lista

  • Existe uma maneira de fazer ls mostrar arquivos ocultos apenas para determinados diretórios?

  • o que grep -v grep faz

  • Como salvar um caminho com ~ em uma variável?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve