Conclusão da Aba Bash: '-bash: EOF inesperado ao procurar correspondência') '-bash: erro de sintaxe: final inesperado do arquivo

17

Estou tentando entrar em uma sessão irb com variáveis de ambiente específicas de um arquivo com este comando:

$ env $(cat env.sh) irb

Mas quando tento pressionar Tab depois de digitar env. para concluí-lo, recebo o seguinte erro:

$ env $(cat env.-bash: unexpected EOF while looking for matching ')'
-bash: syntax error: unexpected end of file

Outra coisa interessante é que, se eu estou logado como root, esse erro não ocorre.

Veja a saída de find ~ -uid 0 :

$ find ~ -uid 0
/home/(redacted)/.rpmdb
/home/(redacted)/.rpmdb/Group
/home/(redacted)/.rpmdb/Conflictname
/home/(redacted)/.rpmdb/Installtid
/home/(redacted)/.rpmdb/Sha1header
/home/(redacted)/.rpmdb/Providename
/home/(redacted)/.rpmdb/__db.002
/home/(redacted)/.rpmdb/Requirename
/home/(redacted)/.rpmdb/Sigmd5
/home/(redacted)/.rpmdb/__db.001
/home/(redacted)/.rpmdb/Obsoletename
/home/(redacted)/.rpmdb/.dbenv.lock
/home/(redacted)/.rpmdb/Name
/home/(redacted)/.rpmdb/Basenames
/home/(redacted)/.rpmdb/Triggername
/home/(redacted)/.rpmdb/Packages
/home/(redacted)/.rpmdb/Dirnames
/home/(redacted)/.rpmdb/__db.003

Alguém pode me explicar por que isso está acontecendo e, em caso afirmativo, como corrigi-lo quando não sou usuário root?

    
por eldosoa 09.01.2015 / 01:29

1 resposta

32

Você encontrou um bug na biblioteca Bash Completion usada pelo Ubuntu.

O que isso significa?

O Ubuntu usa uma biblioteca de conclusão bash para tornar a conclusão do bash inteligente. Esta biblioteca vive em /usr/share/bash-completion/bash_completion .

Essencialmente, esta biblioteca declara algumas funções inteligentes que conhecem os comandos típicos e como completá-los. Sempre que você pressionar Tab , as funções dentro desta biblioteca serão chamadas e tentarão completar sua linha de comando atual. Então, por exemplo, se você digitar apt-get i Tab , ele completará isso em apt-get install . Se você não fonte dessa biblioteca, você só tem o bash padrão, primitivo - assim, por exemplo, se você digitar apt-get i Tab sem ter originado, o bash simplesmente procurará por arquivos no arquivo atual. diretório começando com i e tente completar seu comando de acordo com esses nomes de arquivo.

Por que isso não está acontecendo como root?

Porque quando você usa sudo su para se tornar root , a biblioteca de conclusão bash não é originada. Isso seria diferente se você usasse sudo -i para se tornar root . Eu aposto que você vê o inseto então, não é? Veja por exemplo 'sudo su -' vs 'sudo -i' vs 'sudo / bin / bash' - quando importa qual é usado, ou importa mesmo? se você não estiver familiarizado com o diferenças.

No meu caso, como um usuário normal, a biblioteca é originada quando eu inicio um shell Bash porque ~/.bashrc sources /etc/bash_completion que origina /usr/share/bash-completion/bash_completion .

Se eu usar sudo -i para fazer login como root , a biblioteca será originada porque /etc/profile sources /etc/profile.d/bash_completion.sh , que origina /usr/share/bash-completion/bash_completion .

Por que esse bug está acontecendo?

Tente executar este comando:

$ eval 'quoted=$(cat' env.
bash: unexpected EOF while looking for matching ')'
bash: syntax error: unexpected end of file

Parece familiar? ;-) De fato, foi exatamente isso que aconteceu nos bastidores quando você clicou em Tab no contexto que você descreveu. Mais precisamente, o erro está na função _quote_readline_by_ref declarada por /usr/share/bash-completion/bash_completion . Se você comprou esse arquivo, você deve ter essa função disponível. Então, tente isso:

$ _quote_readline_by_ref '$(cat env.' quoted
bash: unexpected EOF while looking for matching ')'
bash: syntax error: unexpected end of file

Com esses argumentos, a função _quote_readline_by_ref executa, entre outras coisas, eval mencionada acima. Você pode dar uma olhada se quiser. E quando você digitou env $(cat env. Tab , nos bastidores essa função foi chamada exatamente com esses argumentos. Então foi o que aconteceu.

Este eval hack deveria corrigir outro problema , mas acho que ele introduziu esse outro bug no processo.

Como corrijo isso?

Acontece que esse bug já foi denunciado . Depois de ler esse relatório de bug, vejo três maneiras de corrigi-lo:

  1. Patch it: Em um dos comentários do relatório de bug, alguém sugere a substituição da linha

    [[ ${!2} == \$* ]] && eval $2=${!2}
    

    dentro da função _quote_readline_by_ref no arquivo /usr/share/bash-completion/bash_completion pela linha

    [[ ${!2} == \$\'* ]] && eval $2=${!2}
    

    Eu não recomendo fazer isso. A pessoa que escreveu esse comentário não aparece para ser um desenvolvedor do bash-completion . Esse hotfix simplesmente fará com que o operando à esquerda da instrução seja avaliado como false, evitando assim que eval ocorra. No entanto, sem um bom conhecimento do que essa função deve fazer e em que contextos ela é chamada, não está claro se isso não irá potencialmente quebrar alguma outra funcionalidade pretendida.

  2. Obtenha a versão mais recente: Como também mencionado no relatório de bug, este bug não está presente no git head (em que entre outras mudanças a função _quote_readline_by_ref foi simplificada). Você pode simplesmente clonar a revisão atual do Git:

    git clone https://salsa.debian.org/debian/bash-completion.git
    

    ... e copie a versão mais recente do script bash_completion para /usr/share/bash-completion (sem necessidade urgente de fazer backup da versão antiga, a menos que você se sinta mais seguro - se tiver alguns problemas, sudo apt-get install --reinstall bash-completion deve reverter qualquer mudanças que você fez muito bem.) Esta é a maneira que eu recomendo se você está com pressa para consertar isso. : -)

Note que nenhuma dessas soluções fará o bash completion dentro do trabalho de substituição de comandos: como mencionado no mesmo relatório de bugs, isso está quebrado no Bash 4.3.

  1. Sente-se e espere: Mais cedo ou mais tarde uma nova versão será lançada (o que pode até consertar a conclusão do bash dentro da substituição de comandos) e você a obterá com alguma versão futura do Ubuntu. É para isso que eu vou;)
por Malte Skoruppa 23.01.2015 / 17:21