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 iTablo completerà apt-get install. Se non provi quella libreria, hai solo il completamento bash standard e primitivo - quindi, ad esempio, se digiti apt-get iTabsenza averlo di provenienza, bash cercherà semplicemente i file nella directory corrente iniziando con ie tenterà di completare il comando in base a questi nomi di file.
Perché non sta accadendo come root?
Perché quando usi sudo sute stesso root, la libreria di completamento bash non proviene. Questo sarebbe diverso se sudo -ifacessi 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é ~/.bashrcfonti /etc/bash_completionquali fonti /usr/share/bash-completion/bash_completion.
Se uso sudo -iper accedere come root, la libreria viene fornita perché /etc/profilefonti /etc/profile.d/bash_completion.shquali 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_refdichiarata 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_refsvolge, tra le altre cose, quella evalsopra 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 evalhack 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_refnel file /usr/share/bash-completion/bash_completiondalla 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ò evalaccada. 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_completionscript /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-completiondovresti 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 ;-)