web-dev-qa-db-ja.com

bashの遅いオートコンプリートをデバッグして修正するにはどうすればよいですか?

最近の更新(Ubuntu 12.04 LTS)の後、コマンドラインでのTABの完了が遅くなります。コマンドの一部を入力した後(例:evi [TAB])またはファイル名の一部(例:evince somedocu[TAB])シェルは、常にではありませんが、数秒間ハングします。

個人的には、遅いオートコンプリートよりもパワフルではないオートコンプリートを好みます。簡単な修正はありますか?

編集:コメントに関連する追加情報:

  • PATHはかなり標準的です。 〜/ binにはいくつかのbashスクリプトがあります

    $ echo $PATH
    /home/USERNAME/bin:/usr/local/bin:/usr/bin:/bin:/usr/games
    
  • 作業ディレクトリ内のファイル数が100未満です。

  • オートコンプリート機能は、異常なディスクアクティビティ(システムアップグレード)の後で特に遅くなりました。したがって、/ usr/binやその他のディレクトリを再読み取りすると、遅延が発生した可能性があります。
27
Jan

修正についてはわかりません。遅延が発生する可能性のあるあらゆる種類の問題があります。しかし、調査するためのいくつかのヒントを提供できます。

推測どおり、検索が遅いファイルシステム($PATH、またはbashが補完データを探す場所)のどこかに、応答が遅いファイルシステム上にあるディレクトリがある可能性があります。通常、遅いのはリモートファイルシステムですが、障害が発生しているハードディスク、ハングしたFuseドライバなどの場合もあります。

調査する最初のステップは、set -xを実行して、シェルが完了を生成するために実行するコマンドのトレースを取得することです。一時停止する場所を確認してください。

それでも十分な情報が得られない場合は、大きな銃を持ってきてください。シェルのプロセスID(echo $$)に注意してください。別のターミナルで、strace -f -s9999 -p$$(または別のUNIXフレーバーで実行している場合は strace と同等)を実行します。 Straceは、プロセスによって実行されるシステムコールをリストします。アクセスしてはいけないファイルにアクセスしているように見えるか、または一部のファイルへのアクセスが遅いかどうかを確認します。オプション-Tstraceコマンドラインに追加すると、各システムコールで費やされた時間が表示されます。

* nixボックスがLDAPクライアントとして設定されている場合、ローカルユーザーとしてログインした場合でも、この問題が発生する可能性があります。

退屈なデバッグ情報:set-xを使用したデバッグで、次の時点でハングしていた完了が見つかりました:

> 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

確認:ハングアップしたls ~*で確認しました。私のLDAPサーバーが遅いことがわかりましたが、これはbashの完了やlsなどには影響しないはずです。

解決策:ああ、bash-completion + ldapに対して bug filed があり、新しいバージョンで修正される予定です。そして、待機したくない場合は simple patch を使用します。タブの完成が再び速いです。

リンクが消えた場合のパッチファイルは次のとおりです。それは単に行545と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

このパッチを有効にするには、現在のsshセッションを終了して再ログインする必要があります。

20
Jeff Ward

別の戦略は、Bash構成ファイルを調べて、すべての完了を非アクティブにすることです。次に、それが速いかどうかをテストします。高速でない場合は、低速(リモート)ディスクに関連している可能性があります。しかし、それより速い場合は、遅延の原因となったものを見つけるまで、少しずつ補完を有効にすることができます。

私の/etc/bash.bashrcこの部分がありました:

if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  Elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

そして私のローカル~/.bashrcはまったく同じでした。そのため、完了コードが2回含まれるようになり、あいまいなディレクトリ名を部分的に完了すると、どういうわけか速度が低下しました。

1
maikel

Bash-completionを再インストールしてみてください

Sudo apt-get install --reinstall bash-completion

私にとってこれはUbuntu 18.04.3 LTSで修正されています

0
arulraj.net

また、一部の人々は Git bash auto complete などの追加のオートコンプリート機能を使用します。 Bashの完了が遅いのは、オートコンプリート機能が正常に動作しないために発生する可能性があります。

私の場合、それはGit bash auto completeでした。私のgit公開鍵が更新されたため、認証に失敗し、ハングアップしました。オートコンプリートを削除すると、再び高速になりました。したがって、私の解決策は、キーを修正して再度有効にすることでした。

0