Completamento scheda Bash: '-bash: EOF imprevisto durante la ricerca della corrispondenza `)' -bash: errore di sintassi: fine imprevista del file


18

Sto cercando di entrare in una irbsessione con variabili di ambiente specifiche da un file con questo comando:

$ env $(cat env.sh) irb

Ma quando provo a premere Tabdopo aver digitato env.per completarlo, viene visualizzato il seguente errore:

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

Un'altra cosa interessante è che se ho effettuato l'accesso come root, questo errore non si verifica.

Ecco l'output di 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

Qualcuno può spiegarmi perché questo sta accadendo e, in caso affermativo, come posso ripararlo quando non sono un utente root?


Come si accede come root?
Muru,

@muru Ho effettuato l'accesso a root utilizzando sudo su.
eldosoa,

Modifica la tua domanda per aggiungere l'output di find ~ -uid 0.
Muru,

@muru Done. Aggiunto l'output nella mia domanda.
eldosoa,

Mi dispiace, ma non come root! Intendevo il tuo normale utente, quindi ~è così /home/something.
Muru,

Risposte:


33

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:

  1. 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.

  2. 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.

  1. 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 ;-)

1
@ con-f-use Sì, questo è tutto! Il repository Git è anche collegato dal sito principale di bash-completamento, motivo per cui non mi ero collegato ad esso nella mia risposta.
Malte Skoruppa,

2
@ con-f-use Il tuo commento mi ha fatto fare qualche ricerca in più su questo bug. Si scopre che non è, e non è mai stato, un bug a monte. Invece, in realtà è un bug introdotto da una patch Ubuntu applicata contro la versione upstream. Finora nessuno sembra aver ridotto questo bug a quella particolare patch. Quindi ho segnalato la mia scoperta nel corrispondente rapporto sui bug di Ubuntu: bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/1312243 .
Malte Skoruppa,

2
Bel lavoro Malte.
Barry Kelly,

1
Grazie per la spiegazione. Al momento della stesura di questo documento, la versione git head ha rimosso il bug e si completa automaticamente come desiderato. EDIT: in realtà, non importa, non lo fa.
user3391564

1
@MaxvonHippel Ho detto che quando si utilizza sudo super diventare root, non si procura la libreria, ma verrà fornito quando si utilizza sudo -iinvece, che è il modo previsto per ottenere una sessione root interattiva. Per quanto riguarda la tua domanda: poiché qualsiasi shell bash legge ~/.bashrcche alla fine genera la libreria e non c'è modo di "estrarre" un file, non vedo un modo completamente semplice. Ecco un possibile trucco: subordinare l'approvvigionamento della libreria ad alcune variabili d'ambiente, diciamo NOCOMPL, non essere definito nel tuo ~/.bashrc...
Malte Skoruppa,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.