it-mure.jp.net

OS Xでbashの完了の読み込みが非常に遅いのはなぜですか?

MacBookProでbashの完了が非常に遅くロードされる理由がわかりません。

~/.bash_profileで次のことを行いました。

echo "Loading BashCompletion..."
if [ -f /opt/local/etc/bash_completion ]; then
    . /opt/local/etc/bash_completion
fi
echo "BashCompletion loaded."

bash_completionの実行時間は通常> 2秒です。

常に新しいタブを開く必要があるターミナルで作業しているとき、それは本当に迷惑だと思います。

これか何かをキャッシュする方法はありますか?

(私はiTerm2を使用しており、これはMacの元の端末でも同様に遅いことに注意してください)。

16
disappearedng

短いバージョン:_/usr/local/etc/bash_completion_から1行を削除すると、新しいタブを開く時間が10秒から1/4秒に短縮されました。詳細については、以下をお読みください。

自作のbash-completionを使用していますが、同じ問題が発生しました。ターミナルを開くたびに、bash完了スクリプトをロードするのに10秒以上かかりました。

ほとんどの場合、それはhave()関数の1行で占められているようです。コマンドラインプログラムがインストールされているかどうかを判断するためのtypeの呼び出しです。

デフォルトのhave()関数と、提供されているすべてのbash完了スクリプトを使用すると、スクリプトをロードするのに10.561秒かかります(の_. /opt/local/etc/bash_completion_行の前にtimeを付けることで報告されます。私の_.bash_profile_ファイル。

_PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type $1 &>/dev/null &&_スクリプトの_/usr/local/etc/bash_completion_行をコメントアウトした後(_have=yes_行を残して、新しいターミナルを開くのにかかる時間はわずか0.258秒です。不要な完了スクリプト(シンボリックリンク)を削除することで、この時間をさらに短縮できます。 )_/usr/local/etc/bash_completion.d_ディレクトリから。

typeの呼び出しに時間がかかる理由がわかりません。次にそれを調査しています。

このアプローチの潜在的な欠点の1つは、bash完了関数を使用しない場合でも、それらがメモリにロードされることです。 have()関数は、コマンドまたはアプリケーションがインストールされているかどうかを確認します。そうでない場合、完了スクリプトは通常、役に立たないため、自分自身をロードする必要がないことを決定します。

現時点では、トレードオフに満足していますが、時間のあるときにtypeの問題を引き続き調査します。より良い解決策が見つかったら、回答を更新します。

10
godbyk

MacOSでの新しいシェルの起動時間が遅すぎるという結論に達した人にとって、これはソリューション

実際、brewを介してインストールできる2つのパッケージがあることを発見しました。私はbash-completionパッケージを何年もインストールしていて、その間にBash 3から4、そして今は5になりましたが、それを疑うことはありませんでした。問題を再検討し、このStackOverflowの議論にしばしば遭遇します。

別のパッケージ、[email protected]があります!

違いは何ですか? bash-completionはBashバージョン3.2用です。 [email protected]は、Bashバージョン4.1以降および5用です。

古いbash-completionパッケージを削除し、[email protected]をインストールすると、シェルの起動時間が605ミリ秒から244ミリ秒に短縮されました。これは速度の大幅な向上です。

brew info統計によると、前者のインストール数は非常に多いのに対し、後者のインストール数は非常に少ないため、私たちの多くはこれと同じ間違いを犯していると思います。

enter image description here

現在選択されている回答 は、いくつかの行をコメントアウトすることに言及していることに注意してください。これにより、起動時間がわずかに改善されます(古いbash-completionパッケージを使用している場合、多くの場合そうです)が、新しい[email protected]パッケージには何の影響もありません。この新しいパッケージは、何があっても高速です。つまり、ハッキングは必要ありません。

TL; DR:

brew uninstall bash-completion && brew install [email protected]

.bashrcまたは.bash_profileファイル内の補完ファイルへのソースパスを更新することを忘れないでください。

出典:


やや関連するトピックとして、私はrcloneユーティリティを頻繁に使用するので、インストールされています。また、たまたま これまでに見た中で最大の完了ファイル があります。これを削除すると、シェルの起動時間が最大120ミリ秒に短縮されます。これは非常に高速です。


編集:

この問題を説明する技術的な詳細が必要な人のために、私は Homebrewフォーラムで詳細に書いています 。要約すると、[email protected]が非常に高速である理由は、すべての完了ファイルを熱心にロードしないように記述されているためです。代わりに、コンプリーションファイルをオンデマンドでロードするか、作成者が説明しているように、非熱心な方法でロードします。

7
danemacmillan

Godbykの答えが私に与えたという考えで、私のPATH変数には、バイナリがないか存在しないディレクトリがいくつかあることがわかりました。それらを削除すると、大幅に高速化されました。言い換えれば、これは私が私のbashrcに持っていたPATHです:

PATH="$GOPATH/bin:/some/directory/not/existing:/some/empty/directory:/some/directory/without/binaries:$PATH"

そして、私はそれを次のように変更しました:

PATH="$GOPATH/bin:$PATH"

これは、そのbash補完のhave関数が各コマンドを検索し、それらのバイナリごとにアクセスする予定の役に立たないディレクトリが多すぎて、それらを削除すると高速化されたためです。

3

私も同じ問題を抱えていました。いくつかの簡単なデバッグのトリックで、根本的な原因がわかりました。

まず、DEBUG modeを有効にして、何が起こっているかを確認します。

export BASH_COMPLETION_DEBUG=true

これにより、コンソールへの詳細な印刷が可能になるため、最後のコマンドを確認できます。これで、スクリプトをバックグラウンドで実行でき、何が起こっているかがわかります。

. /opt/local/etc/bash_completion &

PIDは考慮しないでください。これは、psまたはpstreeでトレースできます。

pstree -p <the PID>

| |     \-+= 82095 mfellows -bash
| |       \-+- 82103 mfellows -bash
| |         |-+- 82104 mfellows cargo --list
| |         | \--- 82106 mfellows rustc -vV --cap-lints allow

ご覧のとおり、それはいくつかのRust関連するコマンドを開始しましたが、これには時間がかかりました。

/opt/boxen/homebrew/etc/bash_completion.d/cargoを一時的に削除すると、症状が解決しました。

0
Matthew Fellows