スクリプトを何度もインポートしないでください

スクリプトを何度もインポートしないでください

現在のMacで端末を開くと、自動的に次のように呼び出されます。

source ~/.bash_profile

~/.bashrcしかし、私を混乱させるのは私のシェルです~/.profile。しかし、それはおそらく典型的なことでしょう。

sourceで使用または継承されたスクリプトがたくさんあります.。これらの呼び出しを入れると、~/.bash_profile新しいシェルウィンドウをロードするのに時間がかかることがあり、時々3〜4秒かかることがあり、これは古くなることがあります。私はこれらのスクリプトを一度だけインポートし、私のファイルに何らかの方法でそれを継承させる方法があると思います~/.bash_profile

私の ~/.bash_profile から source ~/.bashrc または source ~/.profile を呼び出すことは私が望むものではなく、おそらく悪い考えです。これは、各新しいシェルがゆっくりロードされる問題を解決できないため、私がしたいことではありません。

新しいbash端末ウィンドウを開くたびに、次の内容が記録されます。

starting to load /etc/profile
finished loading /etc/profile
starting to load bash_profile
finished loading bash_profile

これは言葉ですが、残念です。新しいシェルを開くたびに実際にロードする必要がありますか?毎回すべてをリロードする必要がないように素晴らしい継承を実行できないのはなぜですか?

問題を示す動画を作成しました。私が定期的に使用する端末アプリケーションは4つあります。

terminal.app                  # misbehaves
iterm2                        # misbehaves
webstorm terminal emulator    # misbehaves
vscode terminal emulator      # behaves!

VSCodeは実際に私が望む方法で実行されます。私の考えでは、親シェルに〜/ .bash_profileをロードしてこれを行い、vscodeが起動したときに一度だけ実行するようです。アプリケーションのすべてのターミナルウィンドウは、この親シェルのサブシェルです。

この動画で問題が明確になることを願っています。 https://www.uselooom.com/share/4e62f0cb24434c4a83b8bd32844b596a

これは妥当な質問です。ほとんどのターミナルアプリケーションはすべての操作を誤って実行しますが、非常に奇跡的に、MicrosoftのVSCodeは実際にすべての操作を正しい方法で実行します。次の質問を参照してください。

https://youtrack.jetbrains.com/issue/WEB-31390

答え1

陳腐な表現はソースよりもソースを中心に書く方が良いのではないかと思います。 (例:Cヘッダファイル)

[[ "${_NAME_OF_THIS_LIBSCRIPT:-""}" == "yes" ]] && return 0
_NAME_OF_THIS_LIBSCRIPT=yes

これにより、複数の場所で共有されるコンテンツを含める必要があるスクリプトファイルを取得するたびに同じ定型句を繰り返す必要がなくなります。それとも私が何かを見逃しているのでしょうか?正直言って、私はbashプログラミングの専門家ではないので、他の人の意見を聞きたいです。

答え2

今朝私は私のファイルから多くの個人情報を移動し、bash_profileというbashrc新しいファイルに追加しましたprivaterc

私のprivatercファイルに次の変数を設定しました。

PRIVATERC_RUN=yes 

今私の項目にbash_profile次の行を追加しました。

[[ $PRIVATERC_RUN != yes && -f ~/.privaterc ]] && source ~/.privaterc

privatercこれにより、そのシェルから以前にリソースがインポートされなかった場合にのみリソースがインポートされます。


また、あなたが見ている奇妙なプロフィールについて私がコメントにリンクした記事には、Macについて次のように記載されています。

Mac OS X—例外

ターミナルウィンドウのガイドラインの1つの例外は、Mac OS XのTerminal.appです。このアプリはデフォルトで、新しいターミナルウィンドウごとにログインシェルを実行し、.bashrcの代わりに.bash_profileを呼び出します。他のGUI端末エミュレータも同じことができますが、ほとんどはそうではありません。

答え3

rcファイルに一意の変数(1バイト以上)を配置し、bash_profileをインポートする前に長さが0より大きいことを確認してください。

if [ ! X”” = X”$uniq_var” ] ; then . ~/.bash_profile ; fi

MacOSでログインシェルとしてbashを設定したところ、この問題は発生しません。たぶん彼らはまた何かを変えるかもしれません。

答え4

これはHiroshi_Uの回答に基づいたテスト版です。

後で何かを変更して更新された結果を得ようとしたら、関数が最新の状態にならないようにmylib.sh機能をテストしたいと思います。新規作成するには$ source mylib.sh;sysLog Hey設定を解除する必要があります。 andのようなものを生成するので、_NAME_OF_THIS_LIBSCRIPTスクリプトファイルで実行されているのか、シェルで実行されているのかをテストしました。$ echo $0-sh-bash-

mylib.sh

#!/bin/sh

MY_BASE=$0
[[ "${_NAME_OF_THIS_LIBSCRIPT:-""}" == "yes" ]] && return 0
[[ "${MY_BASE:0:1}" != "-" ]] && _NAME_OF_THIS_LIBSCRIPT=yes

function sysLOG() {
    echo $1 $_NAME_OF_THIS_LIBSCRIPT
}

テストファイル

#!/bin/sh

source /tmp/mylib.sh
sysLOG 1
source /tmp/mylib.sh
sysLOG 2
source /tmp/mylib.sh
sysLOG 3

$ test.sh;echo $_NAME_OF_THIS_LIBSCRIPT
1 yes
2 yes
3 yes

$ source mylib.sh;sysLog Hey;echo $_NAME_OF_THIS_LIBSCRIPT
Hey! yes

いいえ[[ "${MY_BASE:0:1}" != "-" ]] &&

$ source mylib.sh;sysLog Hey;echo $_NAME_OF_THIS_LIBSCRIPT
Hey! yes
yes

関連情報