Você encontrou um bug na biblioteca Bash Completion usada pelo Ubuntu.
O que isto significa?
O Ubuntu usa uma biblioteca de conclusão do bash para torná-lo inteligente. Esta biblioteca mora /usr/share/bash-completion/bash_completion.
Essencialmente, esta biblioteca declara algumas funções inteligentes que sabem sobre comandos típicos e como concluí-los. Sempre que você pressiona Tab, as funções desta biblioteca são chamadas e tentam concluir sua linha de comando atual. Por exemplo, se você digitar, apt-get iTabisso será concluído apt-get install. Se você não obtiver a fonte dessa biblioteca, terá apenas a conclusão padrão e primitiva do bash - por exemplo, se você digitar apt-get iTabsem a ter originado, o bash simplesmente procurará arquivos no diretório atual começando com ie tentará concluir seu comando de acordo com esses nomes de arquivos.
Por que isso não está acontecendo como raiz?
Porque quando você usa sudo supara fazer a si mesmo root, a biblioteca de conclusão do bash não é originada. Isso seria diferente se você costumava sudo -ifazer a si mesmo root. Aposto que você vê o bug, não é? Veja, por exemplo, 'sudo su -' vs 'sudo -i' vs 'sudo / bin / bash' - quando importa o que é usado ou importa? se você não estiver familiarizado com as diferenças.
No meu caso, como usuário normal, a biblioteca é originada quando eu inicio um shell Bash porque ~/.bashrcorigina /etc/bash_completionquais origens /usr/share/bash-completion/bash_completion.
Se eu usar o sudo -ilogin como root, a biblioteca será originada porque /etc/profileorigina /etc/profile.d/bash_completion.shquais origens /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 o que aconteceu nos bastidores quando você acessou Tabo contexto que descreveu. Mais precisamente, o bug está na função _quote_readline_by_refdeclarada por /usr/share/bash-completion/bash_completion. Se você originou esse arquivo, deveria ter essa função disponível. Então, tente o seguinte:
$ _quote_readline_by_ref '$(cat env.' quoted
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Diante desses argumentos, a função _quote_readline_by_refexecuta, entre outras coisas, a evalmencionada 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 evaltruque deveria corrigir outro problema , mas acho que introduziu esse outro bug no processo.
Como faço para corrigir isso?
Acontece que esse bug já foi relatado . Depois de ler o relatório de erros, vejo três maneiras de corrigi-lo:
Corrigir: em um dos comentários nesse relatório de bug, alguém sugere substituir a linha
[[ ${!2} == \$* ]] && eval $2=${!2}
dentro da função _quote_readline_by_refno arquivo /usr/share/bash-completion/bash_completionpela linha
[[ ${!2} == \$\'* ]] && eval $2=${!2}
Eu recomendo não fazer isso. A pessoa que escreveu esse comentário não parece ser um desenvolvedor de conclusão do bash . Esse hotfix simplesmente fará com que o operando esquerdo da instrução seja avaliado como falso e, assim, evite que isso evalaconteça. No entanto, sem um bom conhecimento do que essa função deve fazer e em quais contextos ela é chamada, não está claro se isso não irá potencialmente quebrar alguma outra funcionalidade pretendida.
Obtenha a versão mais recente: Como também mencionado no relatório de erros, esse bug não está presente no git head (em que, entre outras alterações, a função _quote_readline_by_reffoi 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 bash_completionscript para /usr/share/bash-completion(não há necessidade urgente de fazer backup da versão antiga, a menos que isso a faça se sentir mais segura - se você tiver alguns problemas, sudo apt-get install --reinstall bash-completiondeve reverter todas as alterações feitas.) recomendo se você estiver com pressa para corrigir isso. :-)
Observe que nenhuma dessas soluções fará com que a conclusão do bash dentro da substituição de comandos funcione: conforme mencionado no mesmo relatório de erros, isso está quebrado no Bash 4.3.
- Sente-se e espere: mais cedo ou mais tarde, uma nova versão será lançada (o que pode até corrigir a conclusão do bash na substituição de comandos) e você a obterá em alguma versão futura do Ubuntu. É para isso que eu estou indo ;-)