Entenda o significado de `$ _`


12

Você poderia explicar as seguintes frases do manual do Bash sobre $_, especialmente as partes em negrito, talvez com alguns exemplos?

  1. Na inicialização do shell, defina o nome do caminho absoluto usado para chamar o shell ou script de shell que está sendo executado conforme passado no ambiente ou na lista de argumentos .

  2. Posteriormente , expande para o último argumento para o comando anterior, após a expansão.

  3. Defina também o nome do caminho completo usado para chamar cada comando executado e colocado no ambiente exportado para esse comando .

  4. Ao verificar o correio , este parâmetro mantém o nome do arquivo de correio.


4
-1 pergunta incerta e não completamente pesquisada. O que você tentou? Onde suas expectativas se desalinharam com o texto? Você não entende honestamente a palavra "subsequentemente"? Se um novo usuário fizesse a mesma pergunta, eu teria as mesmas perguntas (apesar da minha curiosidade inata semelhante de exatamente como as coisas funcionam).
Jeff Schaller

Respostas:


20

Concordo que não está muito claro.

1. Na inicialização do shell,

  • se a _variável estava no ambiente que bashrecebeu , bashela permanece intocada.

    Em particular, se isso bashshell foi invocado por outro bash shell (embora zsh, yashe algumas kshimplementações também fazê-lo), então isso bashshell irá ter definido a _variável de ambiente para o caminho do comando a ser executado (que é o 3º ponto na sua pergunta). Por exemplo, se bashfor chamado para interpretar um script como resultado de outra bashinterpretação do shell:

    bash-script some args

    Isso bashjá passou _=/path/to/bash-scripno ambiente fornecido bash-script, e é esse o valor inicial da $_ bashvariável no bashshell que interpreta esse script.

    $ env -i _=whatever bash -c 'echo "$_"'
    whatever
    
  • Agora, se o aplicativo que invoca não passa uma _variável de ambiente , o bashshell invocado será inicializado $_para argv[0]receber a si próprio o que poderia ser bash, /path/to/bashou /path/to/some-scriptou qualquer outra coisa (no exemplo acima, isso seria /bin/bashse o estrondo do script foi #! /bin/bash ou /path/to/bash-script dependendo do sistema ).

    Portanto, esse texto é enganoso, pois descreve o comportamento do chamador que bashnão tem controle. O aplicativo invocado bashpode muito bem não ser definido $_(na prática, apenas alguns shells e alguns aplicativos interativos raros o fazem, execlp()por exemplo), ou pode ser usado para algo completamente diferente (por exemplo, o ksh93define *pid*/path/to/command).

    $ env bash -c 'echo "$_"'
    /usr/bin/env   (env did not set it to /bin/bash, so the value we
                   get is the one passed to env by my interactive shell)
    $ ksh93 -c 'bash -c "echo \$_"'
    *20042*/bin/bash
    

2. Posteriormente

O subseqüente também não é muito claro. Na prática, isso é assim que bashinterpreta um comando simples no ambiente atual do shell.

  • No caso de um shell interativo , esse será o primeiro comando simples interpretado, /etc/bash.bashrcpor exemplo.

    Por exemplo, no prompt de um shell interativo:

     $ echo "$_"
     ]      (the last arg of the last command from my ~/.bashrc)
     $ f() { echo test; }
     $ echo "$_"
     ]      (the command-line before had no simple command, so we get
             the last argument of that previous echo commandline)
     $ (: test)
     $ echo "$_"
     ]      (simple command, but in a sub-shell environment)
     $ : test
     $ echo "$_"
     test
    
  • Para um shell não interativo , seria o primeiro comando no $BASH_ENVou do código alimentado para esse shell se $BASH_ENVnão estiver definido.

3. Quando o Bash executa um comando

O terceiro ponto é algo diferente e é sugerido na discussão acima.

bash, como algumas outras shells, passará uma _variável de ambiente para os comandos executados que contêm o caminho bashusado como o primeiro argumento para as execve()chamadas do sistema.

$ env | grep '^_'
_=/usr/bin/env

4. Ao verificar o correio

O quarto ponto é descrito em mais detalhes na descrição da MAILPATHvariável:

'MAILPATH'

Uma lista de nomes de arquivos separados por dois pontos que o shell verifica periodicamente por novos emails .

Cada entrada da lista pode especificar a mensagem que será impressa quando um novo email chegar no arquivo , separando o nome do arquivo da mensagem com um '?' Quando usado no texto da mensagem, '$ _' se expande para o nome do arquivo de mensagens atual.

Exemplo:

$ MAILCHECK=1 MAILPATH='/tmp/a?New mail in <$_>' bash
bash$ echo test >> /tmp/a
New mail in </tmp/a>

4

Tente este exemplo simples:

echo "$_"
echo "test"
echo "$_"

Execute-o fornecendo o caminho absoluto ( /home/$USERNAME/test.sh); resultado:

/home/$USERNAME/test.sh
test
test

Primeiro $_contém o caminho que você usou para invocar o script e o segundo contém o primeiro argumento para o meio echo. Para o terceiro item da lista, se você iniciar um novo terminal e digitar echo $_ , será mostrada a variável que contém o PATHque normalmente é usado para procurar e chamar comandos (na minha máquina Ubuntu) em um shell normal ou caminho absoluto para o seu .bashrsarquivo em um shell de login.

Para o item quatro da página do manual bash:

Quando usado no texto da mensagem, $_expande para o nome do arquivo de mensagens atual.


Obrigado. (1) você pode explicar o terceiro caso com exemplos? (2) Quando abro uma nova aba do terminal gnome, a saída de echo $_é EDITORe por que é? Qual caso segue? (3) Você pode dar um exemplo de como verificar e-mails e usar $_neste caso?
Tim

Abra o seu .bashrce comente todas as linhas lá. Mantenha apenas uma única linha contendo um comando como echo "test"ou similar. Salvar e fechar. Então corra bashe imediatamente echo $_. Este último eco deve imprimir teste na saída.
amigos estão dizendo sobre cafeteria

Para a parte de correio, não usei o correio Unix e não tenho um correio em funcionamento instalado no meu sistema agora, portanto não posso dar um exemplo. Mas deve ser óbvio, se você seguir a descrição MAILPATHem linuxcommand.org/lc3_man_pages/bash1.html
coffemug

1
Para sua informação, a versão canônica e atualizada do manual do bash é: gnu.org/software/bash/manual/bashref.html . É a versão 4.3, enquanto a página de comando linux era 4.1.
Jeff Schaller

1

Para o caso 2, um exemplo vale mais que mil palavras:

mkdir my_long_dir
cd $_

Faz o que você imagina / espera. Dá-me um espaço reservado simples quando estou na linha de comando para evitar que eu me repita.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.