回答:
2013年の更新:bash-completionのほとんどは、必要な場合にのみ完了を自動ロードするように書き直されました。コアスクリプトは、今では非常に洗練されています。
完了スクリプトは、シェルスクリプト標準では巨大な場合があります。私がアクセスできる1台のサーバーでは、ほぼ1700行(57 KB)であり、これは単なるコアスクリプトです。で/etc/bash_completion.d
ある〜様々な他のコマンドのための200個の追加のスクリプト(openssl
、mutt
、mount
...)、25537行または1.2メガバイト合計。各スクリプトは、ソース化されると、完了ハンドラーを定義する前にコマンドが実際に使用可能かどうかを確認します。この場合〜330回。それぞれの場合、$PATH
指定された名前の実行可能ファイルをチェックします。(/usr/bin
メモリにキャッシュされることを期待しますが...)
確かに、でもということだけではない2つのフル秒、負荷に半秒かかります。しかし、それは少なくとも問題の一部かもしれません。実行するdu -hs /etc/bash_completion*
かwc -l /etc/bash_completion{,.d/*} | grep total
、確認する場合。
「トレース」モードで、手動でスクリプトのソースを試すことができます。
set -x
. /etc/bash_completion
実行時に各行が表示されます。時間がかかる特定のコマンドがある場合は、それに注意する必要があります。
(set +x
トレースモードを無効にします。)
私はかなりハック的な解決策を見つけましたが、それはかなり十分に機能しているようです。
~/.bashrc
追加の下部:
trap 'source / etc / bash_completion; トラップUSR1 'USR1 {スリープ0.1; builtin kill -USR1 $$; }&disown
trap 'source /etc/bash_completion ; trap USR1' USR1
シェルがシグナルを受信したときに実行されるハンドラーをセットアップしますSIGUSR1
。ハンドラーが完了をロードするため、ハンドラー自体が非アクティブになります。
{ sleep 0.1 ; builtin kill -USR1 $$ ; } & disown
非同期で少し待ってから、現在のシェルにシグナルを送信します。プロセス制御フィードバックdisown
を抑制bash
するために必要です。sleep
非同期で動作するために必要です。
何らかの理由で、このシェルに発行された最初のコマンドは履歴に記録されません。
time bash -lc true
、ここで適切に動作するかどうかはわかりませんので、何もソースしません。とにかくここで報告されるのは〜0.17sで、それが表示されるのを待つ時間です。true
~0.1s
time source /etc/bash_completion
PS1
USR1
は最後にa を逃します。
補完のロード中にプレースホルダーを使用できます。目を欺くのに十分なはずです。これは明らかに、必要なsource /etc/bash_completion
時間が最初のシェルコマンドを入力して発行するのに必要な時間よりも短い場合にのみ機能します。そうでない場合も同様に遅延します。
アイデアは、偽物をエコーしPS1
、補完をソースし、最終的に端末を消去することです。
あなたPS1
が\u@\h:\w\$
であると仮定すると、彼らはあなたが次のように書くかもしれません:
echo -ne "$USER@$HOSTNAME:${PWD/$HOME/\~}\$ "
source /etc/bash_completion
echo -ne '\e[2J\e[H'
どこ:
2J
端末を消去します。H
カーソルを右上隅に移動します。注:ユーザーがrootであるかどうかを確認し、一貫性の#
代わりに使用することもできます$
。
echo -ne "...$([ $UID = 0 ] && echo '#' || echo '$') "
注:削除すると\e[2J
、ちらつきが回避されますが、プレースホルダーが実際のプロンプトよりも長い場合は、ジャンク文字が残ります。