Hai trovato un bug nella libreria di completamento Bash utilizzata da Ubuntu.
Cosa significa questo?
Ubuntu utilizza una libreria di completamento bash per rendere intelligente il completamento bash. Questa biblioteca vive dentro /usr/share/bash-completion/bash_completion
.
In sostanza, questa libreria dichiara alcune funzioni intelligenti che conoscono i comandi tipici e come completarli. Ogni volta che si preme Tab, le funzioni all'interno di questa libreria vengono chiamate e si tenta di completare la riga di comando corrente. Quindi, ad esempio, se lo digiti apt-get i
Tablo completerà apt-get install
. Se non provi quella libreria, hai solo il completamento bash standard e primitivo - quindi, ad esempio, se digiti apt-get i
Tabsenza averlo di provenienza, bash cercherà semplicemente i file nella directory corrente iniziando con i
e tenterà di completare il comando in base a questi nomi di file.
Perché non sta accadendo come root?
Perché quando usi sudo su
te stesso root
, la libreria di completamento bash non proviene. Questo sarebbe diverso se sudo -i
facessi te stesso root
. Scommetto che vedi il bug allora, vero? Vedi ad esempio 'sudo su -' vs 'sudo -i' vs 'sudo / bin / bash' - quando importa chi viene usato o importa? se non hai familiarità con le differenze.
Nel mio caso, come un normale utente, la libreria viene reperita quando avvio una shell Bash perché ~/.bashrc
fonti /etc/bash_completion
quali fonti /usr/share/bash-completion/bash_completion
.
Se uso sudo -i
per accedere come root
, la libreria viene fornita perché /etc/profile
fonti /etc/profile.d/bash_completion.sh
quali fonti /usr/share/bash-completion/bash_completion
.
Perché sta succedendo quel bug?
Prova a eseguire questo comando:
$ eval 'quoted=$(cat' env.
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Sembra familiare? ;-) In effetti, è esattamente quello che è successo dietro le quinte quando hai colpito Tabnel contesto che hai descritto. Più precisamente, il bug è nella funzione _quote_readline_by_ref
dichiarata da /usr/share/bash-completion/bash_completion
. Se hai acquistato quel file, dovresti avere quella funzione disponibile. Quindi prova questo:
$ _quote_readline_by_ref '$(cat env.' quoted
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Alla luce di questi argomenti, la funzione _quote_readline_by_ref
svolge, tra le altre cose, quella eval
sopra menzionata. Puoi dare un'occhiata se vuoi. E quando scrivevi env $(cat env.
Tab, dietro le quinte quella funzione veniva chiamata esattamente con quegli argomenti. Quindi è quello che è successo.
Questo eval
hack avrebbe dovuto risolvere un altro problema , ma immagino che abbia introdotto questo altro bug nel processo.
Come lo aggiusto?
Si scopre che questo bug è già stato segnalato . Dopo aver letto la segnalazione di bug, vedo tre modi per risolverlo:
Patch: in uno dei commenti in quella segnalazione di bug, qualcuno suggerisce di sostituire la linea
[[ ${!2} == \$* ]] && eval $2=${!2}
all'interno della funzione _quote_readline_by_ref
nel file /usr/share/bash-completion/bash_completion
dalla riga
[[ ${!2} == \$\'* ]] && eval $2=${!2}
Consiglio di non farlo. La persona che ha scritto quel commento non sembra essere uno sviluppatore del completamento della bash . Questo aggiornamento rapido farà semplicemente in modo che l'operando di sinistra dell'istruzione valuti falso e quindi eviterà che ciò eval
accada. Tuttavia, senza una buona conoscenza di cosa dovrebbe fare quella funzione e in quali contesti viene chiamato, non è chiaro se ciò non possa potenzialmente interrompere alcune altre funzionalità previste.
Ottieni la versione più recente: Come menzionato anche in quella segnalazione di bug, questo bug non è presente in git head (in cui tra le altre modifiche la funzione _quote_readline_by_ref
è stata semplificata). Puoi semplicemente clonare l'attuale revisione da Git:
git clone https://salsa.debian.org/debian/bash-completion.git
... e poi copia la versione più recente dello bash_completion
script /usr/share/bash-completion
(non c'è bisogno urgente di eseguire il backup della versione precedente a meno che non ti faccia sentire più sicuro - in caso di problemi, sudo apt-get install --reinstall bash-completion
dovresti ripristinare tutte le modifiche che hai fatto bene.) Questo è il modo in cui consiglio se hai fretta di farlo riparare. :-)
Nota che nessuna di queste soluzioni farà funzionare bash all'interno della sostituzione dei comandi: come menzionato nella stessa segnalazione di bug, questo è rotto in Bash 4.3.
- Siediti e aspetta: prima o poi verrà rilasciata una nuova versione (che potrebbe anche correggere il completamento della bash nella sostituzione dei comandi) e la otterrai con una futura versione di Ubuntu. Questo è quello che sto cercando ;-)