Bash Tab Completion: '-bash: Unerwartetes EOF bei der Suche nach übereinstimmendem `)' -Bash: Syntaxfehler: Unerwartetes Dateiende

18

Ich versuche, eine irbSitzung mit bestimmten Umgebungsvariablen aus einer Datei mit dem folgenden Befehl zu starten:

$ env $(cat env.sh) irb

Aber wenn ich drücken versuchen , Tabnachdem ich geben env.es zu vervollständigen, erhalte ich diese folgende Fehlermeldung:

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

Eine weitere interessante Sache ist, dass dieser Fehler nicht auftritt, wenn ich als root angemeldet bin.

Hier ist die Ausgabe von 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

Kann mir jemand erklären, warum dies geschieht und wenn ja, wie ich es beheben kann, wenn ich kein Root-Benutzer bin?

Eldosoa
quelle
Wie melden Sie sich als root an?
Muru
@muru Ich habe mich mit root angemeldet sudo su.
Eldosoa
Bitte bearbeiten Sie Ihre Frage, um die Ausgabe von hinzuzufügen find ~ -uid 0.
Muru
@muru Fertig. Fügte die Ausgabe in meiner Frage hinzu.
Eldosoa
Tut mir leid, aber nicht als root! Ich meinte als normaler Benutzer, so ~ist das /home/something.
Muru

Antworten:

33

Sie haben einen Fehler in der von Ubuntu verwendeten Bash Completion- Bibliothek gefunden.

Was bedeutet das?

Ubuntu verwendet eine Bash-Vervollständigungsbibliothek, um die Bash-Vervollständigung intelligent zu gestalten. Diese Bibliothek lebt in /usr/share/bash-completion/bash_completion.

Im Wesentlichen werden in dieser Bibliothek einige clevere Funktionen deklariert, die typische Befehle kennen und wissen, wie sie ausgeführt werden. Jedes Mal Tab, wenn Sie drücken , werden Funktionen in dieser Bibliothek aufgerufen und versuchen, Ihre aktuelle Befehlszeile zu vervollständigen. Wenn Sie zum Beispiel Folgendes eingeben apt-get iTab, wird dies zu vervollständigen apt-get install. Wenn Sie diese Bibliothek nicht als Quelle verwenden, haben Sie nur die standardmäßige, primitive Bash-Vervollständigung. Wenn Sie also beispielsweise ohne Quellenangabe apt-get iTabeingeben, sucht Bash einfach nach Dateien im aktuellen Verzeichnis, beginnend mit iund versucht, Ihren Befehl entsprechend zu vervollständigen diese Dateinamen.

Warum passiert es nicht als root?

Denn wenn Sie es verwenden sudo su, um sich selbst zu machen root, wird die Bash-Vervollständigungsbibliothek nicht bezogen. Das wäre anders, wenn du es sudo -iselbst gemacht hättest root. Ich wette, du siehst den Fehler dann, nicht wahr? Siehe zum Beispiel 'sudo su -' vs 'sudo -i' vs 'sudo / bin / bash' - wann spielt es eine Rolle, welche verwendet wird, oder spielt es überhaupt eine Rolle? wenn Sie mit den Unterschieden nicht vertraut sind.

In meinem Fall als normaler Benutzer, wird die Bibliothek stammen , als ich ein Bash - Shell , weil starten ~/.bashrcQuellen /etc/bash_completionwelchen Quellen /usr/share/bash-completion/bash_completion.

Wenn ich mich sudo -ials anmelde root, wird die Bibliothek bezogen, weil /etc/profileQuellen /etc/profile.d/bash_completion.shwelche Quellen /usr/share/bash-completion/bash_completion.

Warum passiert dieser Fehler?

Versuchen Sie diesen Befehl auszuführen:

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

Kommt mir bekannt vor? ;-) Genau das passierte hinter den Kulissen, als Sie Tabin dem von Ihnen beschriebenen Kontext trafen . Genauer gesagt ist der Fehler in der von _quote_readline_by_refdeklarierten Funktion /usr/share/bash-completion/bash_completion. Wenn Sie diese Datei bezogen haben, sollten Sie diese Funktion zur Verfügung haben. Also versuche es als nächstes so:

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

Mit diesen Argumenten _quote_readline_by_referfüllt die Funktion unter anderem die evaloben genannten Aufgaben . Sie können nachsehen, wenn Sie möchten. Und als Sie tippten env $(cat env.Tab, wurde diese Funktion hinter den Kulissen mit genau diesen Argumenten aufgerufen. Das ist also passiert.

Dieser evalHack sollte ein anderes Problem beheben , aber ich denke, er hat diesen anderen Fehler in den Prozess eingebracht.

Wie behebe ich das?

Es stellt sich heraus, dass dieser Fehler bereits gemeldet wurde . Nachdem ich diesen Fehlerbericht gelesen habe, sehe ich drei Möglichkeiten, ihn zu beheben:

  1. Patch it: In einem der Kommentare in diesem Fehlerbericht schlägt jemand vor, die Zeile zu ersetzen

    [[ ${!2} == \$* ]] && eval $2=${!2}

    innerhalb der Funktion _quote_readline_by_refin der Datei /usr/share/bash-completion/bash_completiondurch die Zeile

    [[ ${!2} == \$\'* ]] && eval $2=${!2}

    Ich empfehle dagegen. Die Person, die diesen Kommentar geschrieben hat, scheint kein Entwickler der Bash-Vervollständigung zu sein . Dieser Hotfix bewirkt einfach, dass der linke Operand der Anweisung als falsch ausgewertet wird, und verhindert so, dass dies evalgeschieht. Ohne ein gutes Wissen darüber, was diese Funktion tun soll und in welchem ​​Kontext sie aufgerufen wird, ist jedoch unklar, ob dies möglicherweise eine andere beabsichtigte Funktionalität beeinträchtigt.

  2. Holen Sie sich die neueste Version: Wie auch in diesem Fehlerbericht erwähnt, ist dieser Fehler in git head nicht vorhanden (wobei unter anderem die Funktion _quote_readline_by_refvereinfacht wurde). Sie können einfach die aktuelle Version von Git klonen:

    git clone https://salsa.debian.org/debian/bash-completion.git

    ... und kopieren Sie dann die neueste Version des bash_completionSkripts nach /usr/share/bash-completion(es ist nicht dringend erforderlich, die alte Version zu sichern, es sei denn, Sie fühlen sich sicherer - wenn Sie auf Probleme sudo apt-get install --reinstall bash-completionstoßen , sollten Sie die von Ihnen vorgenommenen Änderungen rückgängig machen.) So verhalte ich mich empfehlen, wenn Sie es eilig haben, dies zu beheben. :-)

Beachten Sie, dass keine dieser Lösungen die Bash-Vervollständigung innerhalb der Befehlsersetzung bewirkt: Wie im selben Fehlerbericht erwähnt, ist dies in Bash 4.3 nicht möglich.

  1. Lehnen Sie sich zurück und warten Sie: Früher oder später wird eine neue Version veröffentlicht (die möglicherweise sogar die Bash-Vervollständigung innerhalb der Befehlsersetzung behebt) und Sie werden sie mit einer zukünftigen Ubuntu-Version erhalten. Dafür gehe ich ;-)
Malte Skoruppa
quelle
1
@ con-f-use Ja, das war's! Das Git-Repo ist auch von der Hauptseite der Bash-Vervollständigung verlinkt, weshalb ich in meiner Antwort nicht darauf verlinkt hatte.
Malte Skoruppa,
2
@ con-f-use Ihr Kommentar hat mich veranlasst, weitere Nachforschungen zu diesem Fehler anzustellen. Es stellt sich heraus, dass es kein Upstream-Bug ist und war. Stattdessen handelt es sich tatsächlich um einen Fehler, der durch einen Ubuntu-Patch verursacht wurde, der gegen die Upstream-Version angewendet wurde. Bisher hat anscheinend noch niemand diesen Fehler auf diesen bestimmten Patch eingegrenzt. Also habe ich meine Entdeckung im entsprechenden Ubuntu-Fehlerbericht gemeldet: bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/1312243 .
Malte Skoruppa,
2
Gute Arbeit, Malte.
Barry Kelly
1
Danke für die Erklärung. Zum jetzigen Zeitpunkt hat die Git-Head-Version den Fehler behoben und wird wie gewünscht automatisch vervollständigt. EDIT: Eigentlich, egal, tut es nicht.
User3391564
1
@MaxvonHippel Ich sagte, wenn Sie sudo suroot werden, wird die Bibliothek nicht als Quelle verwendet, aber wenn Sie sie stattdessen verwenden, wird sie als Quelle verwendet. Dies sudo -iist der beabsichtigte Weg, um eine interaktive Root-Sitzung zu erhalten. Was Ihre Frage betrifft: Da jede Bash-Shell liest, von ~/.bashrcder letztendlich die Bibliothek stammt, und es keine Möglichkeit gibt, eine Datei aus der Quelle zu entfernen, sehe ich keinen völlig einfachen Weg. Hier ist ein möglicher Hack: Machen Sie das Sourcing der Bibliothek von einer Umgebungsvariablen abhängig, die beispielsweise in Ihrer , ...NOCOMPL~/.bashrc
Malte Skoruppa,