.bash_profile
端末を開くたびにスクリプトを実行するのに数秒かかりますので、これは非常に迷惑になります。
テストの結果、いくつかのコマンドに時間がかかることがわかったので、そのコマンドを.bash_profile
新しいスクリプトに移動しました。.bash_profile_load_in_background
.bash_profile
バックグラウンドでソースを見つけようとします。
.bash_profile
# fast stuff here
#.....
# slow stuff here
source .bash_profile_load_in_background & # notice the &
いくつかの変数を設定していますが、.bash_profile_load_in_background
バックグラウンドで送信すると正しく伝播されません。source
&
以下は「遅い」スクリプトの要約バージョンです。
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
if type brew &>/dev/null; then
HOMEBREW_PREFIX="$(brew --prefix)"
if [[ -r "${HOMEBREW_PREFIX}/etc/profile.d/bash_completion.sh" ]]; then
source "${HOMEBREW_PREFIX}/etc/profile.d/bash_completion.sh"
else
for COMPLETION in "${HOMEBREW_PREFIX}/etc/bash_completion.d/"*; do
[[ -r "$COMPLETION" ]] && source "$COMPLETION"
done
fi
fi
if [ -f $(brew --prefix)/etc/bash_completion ]; then
. $(brew --prefix)/etc/bash_completion
fi
# parse the git branch
gb() {
__git_ps1
}
# change the prompt to show working directory and git branch
PS1="\[\e[32m\]\w \[\e[91m\]\$(gb)\[\e[00m\]? "
PS1
バックグラウンドスクリプトが完了すると、プロンプトが変わらないことが簡単にわかります。
一方、「ブロック」スクリプトをインラインで受け取ると、すべてが期待どおりに機能します。
つまり
調整
source .bash_profile_load_in_background & # notice the &
到着
source .bash_profile_load_in_background # REMOVE THE &
なぜこれが起こるのですか?
.bash_profile
簡単な方法でロード時間を短縮する方法はありますか?一部の機能が適用されるまでに数秒かかるかどうかは関係ありませんが、現在の範囲内で適用する必要があります。
答え1
いたずら
この他の答え試したことがうまくいかなかった理由を説明してください。少なくともある程度は機能する秘訣があります。私は本当にそれをお勧めしません。それは.bash_profile
それがうまくいく方法ではありません。
アイデアは次のとおりです。
.bash_profile
一時ファイルを作成し、そのパスを覚えてみましょう。tmpf="$(mktemp)"
(
mktemp
ポータブルではありません。)trap
シェルが一時ファイルをソースとして使用するように設定しますSIGUSR1
。取得したファイルとトラップは不要になるため、トラップの一部としてクリーンアップすることを検討してください。trap ' . "$tmpf" rm "$tmpf" trap - USR1 ' USR1
.bash_profile_background_wizard
バックグラウンドで実行されます。スクリプトは一時ファイルに書き込むことができる必要があるため、記述子またはパス(引数または環境内)を指定してください。例:tmpf="$tmpf" ~/.bash_profile_background_wizard &
このスクリプトは長期実行ジョブを開始し、一時ファイルにシェルコードを記述する必要があります。そうしなければならない立てる関数と変数の定義、長期実行タスクに依存するすべて、準備が整ったときにメインシェルが「受け入れる」ことを望むすべて。実行する操作によっては、スクリプトをスクリプト化するのは簡単ではないかもしれません。一時ファイルがすぐに作成されることを忘れないでください。Fメインシェルで。
declare -p variable >>"$tmpf"
それとも構文が${variable@Q}
役に立ちます。一時ファイルにすべてのコードを記述したら、スクリプトを
SIGUSR1
メインシェルに送信する必要があります。kill -s USR1 "$PPID"
そして出てください。
トラップのため、メインシェルは
.bash_profile_background_wizard
。
ノート
メインシェルが同期コマンドの完了を待っている間に信号が発生した場合コマンドが完了するまでトラップは実行されません。。
シグナルが到着する前に子を生成する場合は、
bash
子がシグナルに反応することを期待しないでください。なぜなら:- PIDが違うので信号が届かないので、
- トラップを継承しません。
bash
ソースを取得する方法でサブキーを生成すると、トリック全体がその.bash_profile
サブキーで始まります。bash
独立して。シグナルが到着する前にバックグラウンドプロセスを生成する場合は、デフォルトのシェルが最終的に一時ファイルをインポートし、独自の環境を変更したときにそのプロセスの環境が更新されるとは期待しないでください。
トラップが実行される前にデフォルトのシェルを終了すると、一時ファイルはそのまま残ります(
trap '…' EXIT
便利かもしれません)。
概念の証拠
次のコードは、インタラクティブBashに貼り付けるためのものです。これにより、アイデアを汚染することなくアイデアをテストできます.bash_profile
。メカニズムは上記と同じです。
# imagine this block is sourced from .bash_profile
{
export PS1='poor prompt > '
tmpf="$(mktemp)"
trap '
. "$tmpf"
rm "$tmpf"
trap - USR1
' USR1
# wizard in background
tmpf="$tmpf" bash -c '
sleep 10 # delay
PS1="RICH PROMPT >>> "
declare -p PS1 >>"$tmpf"
kill -s USR1 "$PPID"
' &
}
# Initially you will see a poor prompt.
# Run few basic commands or keep striking Enter.
# After 10 seconds the prompt should change.
答え2
互換性のない2つを組み合わせようとしています。
このsource
コマンドはシェルにファイルを読み込み、そこにあるコマンドを実行させます。現在のシェル環境で。
非同期操作を開始すると、つまりバックグラウンドで実行コマンドを使用すると、呼び出すシェルとは別に、&
独自の環境でコマンドが実行されます。この環境は親シェル環境のコピーであり、コマンドが終了すると削除されます。バックグラウンド操作では、親シェル環境で環境変数などを設定できません。
コマンドの効果
source .bash_profile_load_in_background &
bash
バックグラウンドで新しいシェルプロセスを開始し、そのプロセスでコマンドを実行しますsource
。その後、変更された環境でプロセスが終了します。
.bash_profile_load_in_background
一人でやったことと効果は同じですスクリプト(自体環境でも動作します。)
関連: