[ -n "$PS1" ]
の目的は何ですか[ -n "$PS1" ] && source ~/.bash_profile;
?この行は.bashrc
ドットファイルに含まれています。買戻契約。
答え1
これはシェルが対話型であることを確認します。この場合、~/.bash_profile
シェルが対話型の場合にのみファイルをインポートします。
バラより「これはシェルインタラクティブですか?」Bashのマニュアルには特定のイディオムが引用されています。 ($-
特殊変数にこの文字が含まれているかどうかをテストしてシェルが対話型であることを確認することは、i
この問題を解決するためのより良い方法でもあります。)
答え2
これは何のためであるか。
これは、シェルが対話型であるかどうかをテストするために広く使用されています。他のシェルでは動作せず、bashでのみ動作します。したがって、については問題ありませんが(愚かな場合).bashrc
は機能しません.profile
(shで読むと、bashはshの可能な実装の1つにすぎず、最も一般的な実装ではありません)。
働く理由(bashでのみ!)
対話型シェルの設定シェル変数PS1
デフォルトのプロンプト文字列として。したがって、シェルがインタラクティブである場合PS1
(ユーザーが.bashrc
それを削除しない限り、これはまだ最上位で起こる可能性がなく、愚かなことと考える.bashrc
ことができます)。
Bashでは、その逆は本当です。 Bashの非対話型インスタンスはPS1
起動時に設定を解除します。この動作はbashに固有のものであり、間違いなくバグです(bash -c '… do stuff with $var…'
isの場合、なぜ動作しないのですか?)。しかし、bashのすべてのバージョン(4.4を含む)(私が書いた最新バージョン)はこれを行います。var
PS1
多くのシステムがPS1
環境にエクスポートされます。多くの異なるシェルがPS1
異なる構文を使用しているため、これは悪い考えです(例:bashプロンプトエスケープとは全く違うzshプロンプトエスケープ)。ただし、これはあまりにも一般的であり、実際に設定PS1
を表示することは、シェルが対話型であるという信頼できる表示ではありません。シェルはPS1
環境から継承できます。
ここではなぜ(間違って)使用されたのですか?
.bashrc
対話式で起動したときに bash が読み取るファイルです。よく知られていないという事実は、bashが.bashrc
isもログインシェルであるということであり、bashの経験的な結論はこれがリモートセッションであるということです(bashは親セッションがあるかどうかをrshd
確認しますsshd
)。 2番目のケースでは、PS1
ドットファイルがまだ実行されていないため、環境に設定される可能性はありません。
ただし、コードがこの情報を使用する方法は逆効果を生む可能性があります。
- シェルが対話型シェルの場合、
.bash_profile
そのシェルで実行されます。しかし、.bash_profile
それはログイン時間スクリプトです。セッションごとに一度だけ実行されるようになっているいくつかのプログラムを実行することもできます。シェルを実行する前に、ユーザーが意図的に異なる値に設定した特定の環境変数をオーバーライドできます。.bash_profile
非ログインシェルで実行すると混乱が発生する可能性があります。 - シェルが非対話型リモートログインシェルの場合、ロードされません
.bash_profile
。ただし、この場合、.bash_profile
非対話型ログインシェルは自動的に/etc/profile
ロードされないため、ロードすると便利です~/.profile
。
人々がこれを行う理由は、ユーザーがGUI(非常に一般的な場合)を介してログインし、.bash_profile
代わりに環境変数設定を置くためだと思います.profile
。ほとんどのGUIログインメカニズムは呼び出されます.profile
が、呼び出されません.bash_profile
(.bash_profile
セッションの一部として読み取るときにbashを実行する必要があります)。 shではなく開始)。この構成では、ユーザーが端末を開くと環境変数が取得されます。ただし、ユーザーはGUIアプリケーションから環境変数にアクセスできず、これは非常に一般的な混乱の原因です。ここで解決策は、環境変数を設定する.profile
代わりに使用することです。との間にブリッジを追加すると、解決されるよりも多くの問題が発生します.bash_profile
。.bashrc
.bash_profile
何をすべきか
現在、シェルが対話型であるかどうかをテストする簡単で移植可能な方法があります。オプションが-i
有効になっているかどうかをテストすることです。
case $- in
*i*) echo "This shell is interactive";;
*) echo "This shell is not interactive";;
esac
これは.bashrc
次のような場合に便利です。.profile
シェルが非対話型の場合にのみ読む——つまり、コードがすることと正反対です!.profile
bashが(非対話型)ログインシェルの場合はお読みください。対話型シェルの場合は読まないでください。
if [[ $- != *i* && -r ~/.profile ]]; then . ~/.profile; fi
答え3
bash
この奇妙な概念は、POSIXシェルクローンで始まらず、クローンでBourne Shell
始まるという事実によるものです。
したがって、POSIX対話型の動作($ENV
対話型シェルが呼び出されます)が後で追加されましたが、bash
よく知られていません。
同様の動作を達成するシェルがあります。これはcsh
cshによって与えられた特定の値です$prompt
。
$prompt not set non-interactive shell, test $?prompt.
$prompt set but == "" .cshrc called by the which(1) command.
$prompt set and != "" normal interactive shell.
ただし、これはBourneシェルやPOSIXシェルでは機能しません。
POSIXシェルの場合、認証された唯一の方法は、対話型シェルのコードをファイルに入れることです。
$ENV
シェル固有の名前があります。たとえば、
$HOME/.kshrc for the korn shell
$HOME/.bashrc for bash
$HOME/.mkshrc for mksh
$HOME/.shrc for the POSIX Bourne Shell
他の人はシェルフラグに言及しましたが、-i
これは安定したプログラミングには適していません。 POSIXはset -i
有効である必要はなく、インタラクティブシェルも$-
含めません。 POSIXでは、シェルをインタラクティブモードに強制するだけi
です。sh -i
変数は$PS1
環境から取得できるため、非対話型モードでも値を持つことができます。実際、非対話型シェルのbash
unset
sはPS1
標準によって付与されず、他のシェルでも施行されません。
したがって、きちんとしたプログラミング(を使用している場合でもbash
)は、インタラクティブシェルのコマンドをに入れることです$HOME/.bashrc
。
答え4
まず、DebianとUbuntuがbashのために設定したことについて話しましょう。後者は他のシステムに関連しています。
シェル起動ファイルの設定については多くのコメントがあります。
私も私の意見がありますが、正しい設定の既存の例を見せようとしています。
私はドキュメントの例を見つけるのが簡単なのでdebuanを使用します。
そしてDebianをたくさん使うので設定テストもうまくいき、
PS1が設定されていることを確認する目的は何ですか?
シェルが対話型かどうかを確認するためです。
これ/etc/profile
Debian のデフォルト値とUbuntu(/usr/share/base-files/profileから):
if [ "${PS1-}" ]; then
if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
読み取る場合:対話型(PS1デフォルト)でbashシェル(ただしデフォルトシェルとして機能しないsh
)の場合は、PS1を特定の新しいシェル(デフォルトシェルではない)に変更します。
これ/etc/bash.bashrc
Debian のデフォルト値以下も含まれます:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
それがすることは非常に明確です:対話型がソースを提供しない場合(残り)。
しかし、/etc/skel/.bashrc
例えば対話型シェルをテストする正しい方法(使用$-
):
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
これはPS1の理由と代替案を明確に示さなければなりません。
正しい順序
報告する設定は避けてください。
シーケンス(システム設定でより具体的なユーザー設定(bash用))は/etc/profile
、、最後/etc/bash.bashrc
に~/.profile
です~/.bashrc
。これは/etc/profile
(root所有)に最も広範な影響(およびより多くのシェル)を置き/etc/bash.bashrc
(またroot所有)に影響しますが、bashにのみ影響します。その後、個人設定があります$HOME
。最初の設定~/.profile
はほとんどのシェル~/.bashrc
(ほぼ同じ~/.bash_profile
)に適用され、bashにのみ適用されます。
~/.bashrc
したがって、ソースが間違っています~/.profile
。 bashの特定のユーザー設定をより一般的な設定に変換します。より多くの殻に影響を与える。もしこの方法:
# ~/.profile: executed by the command interpreter for login shells
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
Bashが実行中であることを確認し、.bashrc
実行中の場合にのみロードします。
これは Debian の上流の決定です。原理は次のように説明される。
実際、~/.profile
ソーシング(または)は、特定のユースケースにすでにロードする必要がある一般的な規則を再適用するため、「悪くない」(「良い」という意味ではありません)。良い意味ではありません。これにより、ファイルソースのループが発生する可能性があります。これは、親ディレクトリをロードする子ディレクトリなどのディレクトリループです。~/.bash_profile
~/.bashrc
この種のクロスソースでは、インタラクティブシェルをチェックするだけの意味があります。シェルは対話型の場合にのみロードされますが、~/.bashrc
反対方向~/.profile
(またはその逆)にロードすることができます。この場合は、対話型シェル検証を使用できます。