Estou tentando entrar em uma irb
sessão 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 estiver logado como root, esse erro não ocorrerá.
Aqui está 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? Em caso afirmativo, como corrigi-lo quando não sou um usuário root?
command-line
bash
auto-completion
eldosoa
fonte
fonte
sudo su
.find ~ -uid 0
.~
é isso/home/something
.Respostas:
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 i
Tabisso será concluídoapt-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ê digitarapt-get i
Tabsem a ter originado, o bash simplesmente procurará arquivos no diretório atual começando comi
e 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 su
para fazer a si mesmoroot
, a biblioteca de conclusão do bash não é originada. Isso seria diferente se você costumavasudo -i
fazer a si mesmoroot
. 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
~/.bashrc
origina/etc/bash_completion
quais origens/usr/share/bash-completion/bash_completion
.Se eu usar o
sudo -i
login comoroot
, a biblioteca será originada porque/etc/profile
origina/etc/profile.d/bash_completion.sh
quais origens/usr/share/bash-completion/bash_completion
.Por que esse bug está acontecendo?
Tente executar este comando:
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_ref
declarada por/usr/share/bash-completion/bash_completion
. Se você originou esse arquivo, deveria ter essa função disponível. Então, tente o seguinte:Diante desses argumentos, a função
_quote_readline_by_ref
executa, entre outras coisas, aeval
mencionada acima. Você pode dar uma olhada, se quiser. E quando você digitouenv $(cat env.
Tab, nos bastidores, essa função foi chamada exatamente com esses argumentos. Então foi o que aconteceu.Este
eval
truque 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
dentro da função
_quote_readline_by_ref
no arquivo/usr/share/bash-completion/bash_completion
pela linhaEu 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
eval
aconteç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_ref
foi simplificada). Você pode simplesmente clonar a revisão atual do Git:... e copie a versão mais recente do
bash_completion
script 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-completion
deve 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.
fonte
sudo su
se torna root, ela não gera a biblioteca, mas será obtida quando você o usasudo -i
, que é a maneira pretendida de obter uma sessão raiz interativa. Quanto à sua pergunta: como qualquer shell bash lê, o~/.bashrc
que eventualmente origina a biblioteca, e não há como "cancelar a fonte" de um arquivo, não vejo uma maneira completamente direta. Aqui está um possível corte: Faça o fornecimento da condicional biblioteca em alguma variável de ambiente, por exemplo,NOCOMPL
, não sendo definida no seu~/.bashrc
...