Ich versuche, eine irb
Sitzung mit bestimmten Umgebungsvariablen aus einer Datei mit dem folgenden Befehl zu starten:
$ env $(cat env.sh) irb
Aber wenn ich drücken versuchen , Tab
nachdem 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?
command-line
bash
auto-completion
Eldosoa
quelle
quelle
sudo su
.find ~ -uid 0
.~
ist das/home/something
.Antworten:
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 i
Tab, wird dies zu vervollständigenapt-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 Quellenangabeapt-get i
Tabeingeben, sucht Bash einfach nach Dateien im aktuellen Verzeichnis, beginnend miti
und 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 machenroot
, wird die Bash-Vervollständigungsbibliothek nicht bezogen. Das wäre anders, wenn du essudo -i
selbst gemacht hättestroot
. 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
~/.bashrc
Quellen/etc/bash_completion
welchen Quellen/usr/share/bash-completion/bash_completion
.Wenn ich mich
sudo -i
als anmelderoot
, wird die Bibliothek bezogen, weil/etc/profile
Quellen/etc/profile.d/bash_completion.sh
welche Quellen/usr/share/bash-completion/bash_completion
.Warum passiert dieser Fehler?
Versuchen Sie diesen Befehl auszuführen:
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_ref
deklarierten 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:Mit diesen Argumenten
_quote_readline_by_ref
erfüllt die Funktion unter anderem dieeval
oben genannten Aufgaben . Sie können nachsehen, wenn Sie möchten. Und als Sie tipptenenv $(cat env.
Tab, wurde diese Funktion hinter den Kulissen mit genau diesen Argumenten aufgerufen. Das ist also passiert.Dieser
eval
Hack 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:
Patch it: In einem der Kommentare in diesem Fehlerbericht schlägt jemand vor, die Zeile zu ersetzen
innerhalb der Funktion
_quote_readline_by_ref
in der Datei/usr/share/bash-completion/bash_completion
durch die ZeileIch 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
eval
geschieht. 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.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_ref
vereinfacht wurde). Sie können einfach die aktuelle Version von Git klonen:... und kopieren Sie dann die neueste Version des
bash_completion
Skripts 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 Problemesudo apt-get install --reinstall bash-completion
stoß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.
quelle
sudo su
root werden, wird die Bibliothek nicht als Quelle verwendet, aber wenn Sie sie stattdessen verwenden, wird sie als Quelle verwendet. Diessudo -i
ist der beabsichtigte Weg, um eine interaktive Root-Sitzung zu erhalten. Was Ihre Frage betrifft: Da jede Bash-Shell liest, von~/.bashrc
der 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