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 / 406674
Accepted
Ole Tange
Ole Tange
Asked: 2017-11-24 15:07:11 +0800 CST2017-11-24 15:07:11 +0800 CST 2017-11-24 15:07:11 +0800 CST

Bash: Por que o alias após a nova linha é ignorado quando executado remotamente?

  • 772

No Bash eu corro:

alias myalias='echo foo
echo bar
echo baz'
myalias

que retorna:

foo
bar
baz

Mas:

ssh localhost "shopt -s expand_aliases &>/dev/null;
alias myalias='echo foo
echo bar
echo baz'
myalias"

Retorna:

foo

Por quê?

bash alias
  • 2 2 respostas
  • 1124 Views

2 respostas

  • Voted
  1. Best Answer
    Bruce
    2017-11-26T18:30:28+08:002017-11-26T18:30:28+08:00

    Acho que você encontrou um bug do Bash. Este bug é específico da opção -c.

    A execução remota não tem nada a ver com o seu problema sobre o alias de várias linhas. Você pode experimentá-lo em seu bash local. Mas não no script bash ou no bash interativo, tente com a -copção, como esta

    bash -c "shopt -s expand_aliases &>/dev/null;
    alias myalias='echo foo
    echo bar
    echo baz'
    myalias"
    

    Mesma saída do seu problema. Apenas fooé impresso.

    Para obter a saída correta (esperada), você deve adicionar pelo menos mais uma linha após myalias, como @cuonglm sugeriu.

    bash -c "shopt -s expand_aliases &>/dev/null;
    alias myalias='echo foo
    echo bar
    echo baz'
    myalias
    :"
    

    Por que aconteceria desta forma? Por que mais uma linha depois myaliasajuda?

    Só quero dizer que isso não faz sentido. Nenhum documento no Bash explica ou menciona esse caso, nem um pouco. Não é suposto funcionar desta forma. Isso é um bug. Depois de ler o código, você terá certeza desse ponto.

    Volte para o primeiro comando problemático. Desta vez, não mude nada, apenas recompile o bash com "ONESHOT" undefined , então você obterá a saída correta (esperada). Sim, você ouviu bem, o comando tem dois comportamentos diferentes apenas por causa da configuração de tempo de compilação diferente.

    Definir ONESHOTou não levará a duas rotas completamente diferentes no código Bash para arquivos -c "command". Se indefinido ONESHOT, -c "command"executará a rota de código normal, que é a rota de código para quase todas as execuções bash, como comando interativo e script bash. Mas se definir ONESHOT, -c "command"executará outra rota específica que é especialmente projetada apenas para ele, para melhorar seu desempenho evitando bifurcações.

    Para este caso, a maneira normal e mais usada pode fornecer a saída correta, enquanto a maneira específica não pode. Acho que o comportamento inconsistente não é o que os autores do Bash desejam. Quanto a qual comportamento é o correto, tendo a pensar que o normal é o correto.

    Alguns detalhes sobre este bug

    O trecho de código a seguir está relacionado ao bug. É da função parse_and_execute() no arquivo builtins/evalstring.c

    while (*(bash_input.location.string))
      {
        ...
      }
    

    Este whileloop será executado por linhas, manipulando uma linha em um loop. Depois de ler myalias, a última linha, no comando (veja acima), a condição em whilese tornará falsa. myaliasé expandido para três linhas de eco, mas apenas um eco é tratado neste loop; os outros dois ecos serão tratados no próximo loop, mas... não há outro loop.

    Se você adicionar mais uma linha após myalias, após read myalias, a condição em whilepermanecerá verdadeira, então os outros dois ecos terão chance de rodar no próximo loop. A última linha depois myaliasserá tratada depois que todos os ecos expandidos por myaliasforem tratados.

    ATUALIZAR

    Esqueci de dizer a versão do Bash envolvida neste problema, que é

    GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
    
    • 5
  2. Ole Tange
    2017-11-26T12:41:42+08:002017-11-26T12:41:42+08:00

    Solução alternativa (inspirada em @cuonglm):

    ssh localhost "shopt -s expand_aliases &>/dev/null;
    alias myalias='ls
    echo foo
    echo bar
    echo baz'
    myalias &&
    true"
    

    Isso preservará o código de saída. O true, no entanto, deve estar em uma nova linha.

    Ainda não explica o porquê. Mas cada vez mais parece um bug.

    • 1

relate perguntas

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

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

    Matriz JSON para bash variáveis ​​usando jq

    • 4 respostas
  • Marko Smith

    A data pode formatar a hora atual para o fuso horário GMT? [duplicado]

    • 2 respostas
  • Marko Smith

    bash + lê variáveis ​​e valores do arquivo pelo script bash

    • 4 respostas
  • Marko Smith

    Como posso copiar um diretório e renomeá-lo no mesmo comando?

    • 4 respostas
  • Marko Smith

    conexão ssh. Conexão X11 rejeitada devido a autenticação incorreta

    • 3 respostas
  • Marko Smith

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

    • 7 respostas
  • Marko Smith

    comando systemctl não funciona no RHEL 6

    • 3 respostas
  • Marko Smith

    rsync porta 22 e 873 uso

    • 2 respostas
  • Marko Smith

    snap /dev/loop em 100% de utilização -- sem espaço livre

    • 1 respostas
  • Marko Smith

    chave de impressão jq e valor para todos no subobjeto

    • 2 respostas
  • Martin Hope
    EHerman Matriz JSON para bash variáveis ​​usando jq 2017-12-31 14:50:58 +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
    Drux A data pode formatar a hora atual para o fuso horário GMT? [duplicado] 2017-12-26 11:35:07 +0800 CST
  • Martin Hope
    AllisonC Como posso copiar um diretório e renomeá-lo no mesmo comando? 2017-12-22 05:28:06 +0800 CST
  • Martin Hope
    Steve Como as permissões de arquivo funcionam para o usuário "root"? 2017-12-22 02:46:01 +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
  • Martin Hope
    Cbhihe Altere o editor padrão para vim para _ sudo systemctl edit [unit-file] _ 2017-12-03 10:11:38 +0800 CST
  • Martin Hope
    showkey Como baixar o pacote não instalá-lo com o comando apt-get? 2017-12-03 02:15:02 +0800 CST
  • Martin Hope
    youxiao Por que os diretórios /home, /usr, /var, etc. têm o mesmo número de inode (2)? 2017-12-02 05:33:41 +0800 CST
  • Martin Hope
    user223600 gpg — o comando list-keys gera uid [ desconhecido ] depois de importar a chave privada para uma instalação limpa 2017-11-26 18:26:02 +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