Quando é '_' uma variável de ambiente de um shell bash?

9

O Manual do Bash diz (manpage, minha ênfase):

When Bash invokes an external command, the variable $_ is set to the full pathname of the command and passed to that command in its environment.

E ( Parâmetros especiais ):

_

($_ , an underscore.) At shell startup, set to the absolute pathname used to invoke the shell or shell script being executed as passed in the environment or argument list. Subsequently, expands to the last argument to the previous command, after expansion. Also set to the full pathname used to invoke each command executed and placed in the environment exported to that command. When checking mail, this parameter holds the name of the mail file.

  1. Em um shell bash, eu corro:

    $ bash
    $ export | grep '_=' 
    

    De acordo com o manual, _ deve ser uma variável de ambiente de o novo shell bash. export deve produzir todos os variáveis de ambiente do novo shell bash, mas não produz %código%. Então, eu me pergunto se _ é uma variável de ambiente do novo concha bash?

  2. Na verdade, em qualquer shell bash, acontece a mesma coisa

    $ export | grep '_='
    

    não produz nada. Então, eu me pergunto se _ é sempre um ambiente variável de um shell bash?

  3. Para comparação:

    $ dash
    $ export  | grep '_='        
    export _='/bin/dash'
    

Meu post é inspirado em comentário de Mike e resposta de Stephane .

    
por Tim 09.04.2018 / 22:43

3 respostas

13

Sim, _ é uma variável de ambiente do novo shell Bash; você pode ver isso executando

tr '
tr '%pre%' '\n' < /proc/$$/environ | grep _=
' '\n' < /proc/$$/environ | grep _=

dentro do shell: mostra o conteúdo do ambiente inicial do shell. Você não verá o primeiro shell porque não havia um shell anterior para defini-lo antes de começar.

Expandir $_ dentro do Bash refere-se ao parâmetro _ special, que é expandido para o último argumento do comando anterior. (Internamente, Bash lida com isso usando uma variável _ shell, que é atualizada toda vez que um comando é analisado, mas isso é realmente um detalhe de implementação. É" não exportado "toda vez que um comando é analisado. ) export não mostra _ porque não é uma variável marcada como exportada; você pode, no entanto, vê-lo na saída de set .

No primeiro exemplo, o novo Bash shell analisa e executa os comandos em seus arquivos de inicialização, portanto, ao executar explore | grep '-=' , _ já foi sobrescrito e marcado como não exportado.

No exemplo dash , parece não executar nenhum arquivo de inicialização, portanto, você está vendo a variável como uma variável de ambiente que foi definida pelo Bash antes de executar dash .

    
por 09.04.2018 / 22:56
9

export sem argumentos lista todos os exportados variáveis . _ não é uma variável, mas está listado como um parâmetro especial .

Um pouco confuso, _ também seria um nome válido para uma variável , ao contrário dos nomes dos outros parâmetros especiais. Pelo menos o Bash 4.4 permite atribuições a ele, sem reclamações. Simplesmente não é útil porque o efeito especial imediatamente substitui o valor.

    
por 09.04.2018 / 23:05
5

Nem todas as variáveis do shell são marcadas como exportadas, como você pode ver na saída de declare -p .

Não faz sentido que bash marque $_ como exportado porque adiciona automaticamente essa variável ao ambiente de processos-filhos mas com um valor diferente daquele que tem em a casca (naquele momento).

Exibi-lo como exportado apenas confundiria o usuário sobre o que acontecerá com o ambiente de comandos externos.

Todas as "variáveis de tempo de execução" BASH* não são exportadas.

    
por 09.04.2018 / 23:00