Wie kann man langsame Autovervollständigung in bash debuggen und beheben?

26

Nach einem kürzlichen Update (Ubuntu 12.04 LTS) ist TAB complete in der Befehlszeile langsam. Nach der Eingabe eines Teilbefehls (z. B. evi [TAB]) oder eines Teildateinamens (z. B. ) bleibt evince somedocu[TAB]die Shell manchmal, aber nicht immer, einige Sekunden lang hängen.

Persönlich würde ich eine weniger leistungsstarke automatische Vervollständigung einer langsamen vorziehen. Gibt es eine einfache Lösung?

Bearbeiten: Zusätzliche Informationen zu Kommentaren:

  • PATH ist ziemlich normal. ~ / bin hat einige Bash-Skripte

    $ echo $PATH
    /home/USERNAME/bin:/usr/local/bin:/usr/bin:/bin:/usr/games
    
  • Die Anzahl der Dateien im Arbeitsverzeichnis beträgt weniger als 100.

  • Die Autocomplete-Funktion war nach ungewöhnlichen Festplattenaktivitäten (System-Upgrade) besonders langsam. Es ist daher möglich, dass das erneute Lesen von / usr / bin und anderen Verzeichnissen die Verzögerung verursacht hat.
Jan
quelle
4
Ist es nicht so, dass Sie die Verwaltung der Festplattengeschwindigkeit mit dem Update aktivieren und die Autovervollständigung darauf wartet, dass die Festplatte aufwacht, um die Autovervollständigung berechnen zu können?
Vincent Nivoliers
2
Kommt es darauf an, wie viele Dateien sich in Ihrem aktuellen Verzeichnis befinden?
Terdon
1
Was sagt # echo $ PATH? Wenn Sie viele (mehrere Zehntausend oder mehr) Dateien in Verzeichnissen in Ihrem Pfad haben, kann dies die Ursache sein.
Stephan

Antworten:

28

Ich weiß nicht, wie man das behebt - es gibt alles Mögliche, was zu Verzögerungen führen kann. Aber ich kann ein paar Tipps zur Untersuchung anbieten.

Vermutlich gibt es irgendwo in einem Suchpfad ( $PATHoder an einem Ort, an dem bash nach Abschlussdaten sucht) ein Verzeichnis , das sich auf einem Dateisystem befindet, das nur langsam reagiert. Normalerweise sind Remote-Dateisysteme langsam, es kann sich aber auch um eine fehlerhafte Festplatte, einen nicht mehr funktionierenden FUSE-Treiber usw. handeln.

Der erste zu untersuchende Schritt besteht darin set -x, eine Ablaufverfolgung der Befehle abzurufen, die die Shell ausführt, um die Vervollständigungen zu generieren. Beobachten Sie, wo es pausiert.

Wenn das nicht genug Informationen gibt, bringen Sie die großen Kanonen. Notieren Sie die Prozess-ID der Shell ( echo $$). Führen Sie in einem anderen Terminal Folgendes ausstrace -f -s9999 -p$$ (oder das Äquivalent von strace, wenn Sie mit einer anderen Unix- Version arbeiten ). Strace listet die vom Prozess ausgeführten Systemaufrufe auf. Sehen Sie nach, ob der Zugriff auf Dateien zu sein scheint, auf die er nicht zugreifen sollte, oder ob der Zugriff auf einige Dateien langsam ist. Durch Hinzufügen der Option -Tzur straceBefehlszeile wird die für jeden Systemaufruf aufgewendete Zeit angezeigt.

Gilles 'SO - hör auf böse zu sein'
quelle
1
Die Zeit, die ich mit Unix verbracht habe und nicht wusste set -x, was für ein cooler Befehl. Sehr "Hacker-Modus beschäftigt"
Matt Fletcher
6
Ps, verwenden set +x, um zum normalen Nicht-Debug-Modus zurückzukehren
Matt Fletcher
19

Wenn Ihre * nix-Box als LDAP-Client eingerichtet ist, besteht möglicherweise dieses Problem, auch wenn Sie als lokaler Benutzer angemeldet sind.

Langweilige Debug-Info: Beim Debuggen mit habe set-xich die Vervollständigung gefunden, die hängen geblieben ist bei:

> set -x
> ls foo<tab>
...                     <--- lots of output removed
...
+ _quote_readline_by_ref foo quoted
+ '[' -z foo ']'
+ [[ foo == \'* ]]      <--- froze here
+ [[ foo == ~* ]]       <--- actually causing the trouble

Bestätige: Ich bestätige das mit ls ~*dem auch hing. Es stellte sich heraus, dass mein ldap-Server träge war, aber das sollte Dinge wie die Bash-Vervollständigung und ls nicht beeinflussen!

Lösung: Aha, es gibt einen Bug gegen Bash-Completion + LDAP, der in einer neueren Version behoben wird, und einen einfachen Patch, wenn Sie nicht warten möchten. Die Tab-Vervollständigung geht wieder schnell, hurra!

Hier ist das Patchfile für den Fall, dass der Link wegfällt. Es entgeht lediglich dem ~ in den Zeilen 545 und 547:

--- /usr/share/bash-completion/bash_completion.orig 2014-11-06 10:36:14.981888369 +0100
+++ /usr/share/bash-completion/bash_completion  2014-11-06 10:36:25.142070963 +0100
@@ -542,9 +542,9 @@
     elif [[ $1 == \'* ]]; then
         # Leave out first character
         printf -v $2 %s "${1:1}"
-    elif [[ $1 == ~* ]]; then
+    elif [[ $1 == \~* ]]; then
         # avoid escaping first ~
-        printf -v $2 ~%q "${1:1}"
+        printf -v $2 \~%q "${1:1}"
     else
         printf -v $2 %q "$1"
     fi

Sie müssen die aktuelle SSH-Sitzung beenden und sich erneut anmelden, damit dieser Patch wirksam wird.

Jeff Ward
quelle
1
Ich hatte genau dieses Problem und der Patch ist gut
radman
2
Dasselbe Problem hier (Debian 8.5) 2 1/3 Jahre zuvor und die Lösung funktioniert wie ein Zauber. Debian 8.6 hat das Problem nicht.
YoMismo
2
Ich habe set -xa millionenfach verwendet, aber ich hätte nie erwartet, dass es auch Leistungsprobleme bei der Fertigstellung zeigt, vielen Dank!
MarcH
Hatte dieses Problem mit Debian 9.8!
Philippe Gachoud
0

Versuchen Sie, die Bash-Vervollständigung erneut zu installieren

sudo apt-get install --reinstall bash-completion

Für mich ist dies in Ubuntu 18.04.3 LTS behoben

arulraj.net
quelle
0

Einige Leute verwenden auch zusätzliche Auto-Vervollständigungsfunktionen wie Git-Bash-Auto-Vervollständigung . Die Verlangsamung der Bash-Vervollständigung kann eine Folge des schlechten Verhaltens dieser zusätzlichen automatischen Vervollständigungsfunktionen sein.

In meinem Fall war es Git Bash Auto-Vervollständigung. Mein öffentlicher Git-Schlüssel wurde aktualisiert, sodass ein fehlgeschlagener Authentifizierungsversuch einen Hang verursachte. Nachdem ich die automatische Vervollständigung entfernt hatte, war es wieder schnell. Meine Lösung bestand also darin, meinen Schlüssel zu reparieren und wieder zu aktivieren.

Nicholas DiPiazza
quelle