unix – .bashrc, .profile, .bash_profile などを選択する
これは恥ずかしいことなのですが、長年 POSIX システムをフルに使ってきた私は、シェルのカスタマイズが .bashrc
か .profile
か、それともどこか他の場所にあるべきなのか、いまだに理解するのに苦労しています。.pam_environment
のような OS 固有の設定ファイルのいくつかは言うまでもありません
はい、私はドキュメントをパズルのように解く方法を知っていますし、各ファイルがいつロードされているか、されていないかを知る方法を知っています。私が疑問に思っているのは、誰かが特定のタイプのカスタマイズをどのファイルに入れるかを決めるための包括的なガイドラインをまとめたことがあるかどうかということです
225 Avdi 2014-07-29
TL;DR:
~/.bash_profile
は超シンプルにして、.profile
と.bashrc
を(順番に)ロードすればいいだけ~/.profile
には、環境変数(PATH
や友人など)のような、特にbashに関係のないものがあります~/.bashrc
には、対話的なコマンドラインで欲しいものが何でも入っています。コマンドプロンプト、EDITOR
変数、私が使用するための bash エイリアス
他にもいくつか注意点があります
グラフィカルアプリケーションや sh (または
sh
として起動された bash) で利用できるものはすべて~/.profile
に入れなければなりません (MUST)~/.bashrc
は何も出力してはいけませんログインシェルでしか使えないはずのものは、
~/.profile
に入るべきです~/.bash_login
が存在しないことを確認する
250 Dan Rabinowitz 2014-07-29
ここ数年、私は多くの時間を無駄にしていたので、私は10分だけではなく、少しのためにこれを研究しました。これがベストなレイアウトなのかどうかは全くわからないのですが、たまたまほとんどのケースで正しく動作するようになっただけなのです
The requirements:
~/.profile
は /bin/sh と互換性がなければなりません – これには bash, dash, ksh, その他ディストロが使用することを選択したものも含まれます環境変数は、コンソールログイン(すなわち’ログイン’シェル)とグラフィカルログイン(すなわちGDM、LightDM、LXDMのようなディスプレイマネージャ)の両方で読めるファイルに入れなければなりません
~/.profile
と~/.bash_profile
の両方を持つことにはほとんど意味がありません。後者が欠けている場合、bash は喜んで前者を使用しますし、bash 固有の行は$BASH
や$BASH_VERSION
のチェックでガードできます*profile
と*rc
の分離は、前者は’login’シェルに、後者はターミナルウィンドウを開くたびに使うということです。しかし、’login’モードのbashは~/.bashrc
をソースにしないので、~/.profile
は手動で行う必要があります
一番シンプルな構成になります
(bash 固有のものを除いて) すべての環境変数を設定する
~/.profile
を持ち、おそらく一行か二行を表示し、bash で実行されている場合は~/.bashrc
をソースとし、それ以外の場合は sh 互換の構文に固執しますexport TZ="Europe/Paris" export EDITOR="vim" if [ "$BASH" ]; then . ~/.bashrc fi uptime
シェル固有の設定を実行する
~/.bashrc
を持ち、Debian のsftp
のようなものを壊さないように、対話モードのチェックで保護しています (bash は対話的でないシェルでも~/.bashrc
をロードするオプションでコンパイルされています)[[ $- == *i* ]] || return 0 PS1='\h \w \$ ' start() { sudo service "$1" start; }
しかし、ある種の非インタラクティブなコマンド(例えば ssh <host> ls
)は ~/.profile
をスキップしてしまうという問題もありますが、環境変数はそれらのコマンドにとっては非常に便利でしょう
特定のディストリビューション (例: Debian) は、このような非対話型ログイン用に
~/.bashrc
をソースにするオプションを付けて bash をコンパイルしています。この場合、すべての環境変数 (export ...
行) を別のファイル~/.environ
に移動し、.profile
と.bashrc
の両方からソースを作成し、二度手間にならないようにガードを付けておくと便利ですif ! [ "$PREFIX" ]; then # or $EDITOR, or $TZ, or ... . ~/.environ # generally any variable that .environ itself would set fi
残念ながら、他のディストリビューション (例えば Arch) では、あまり良い解決策を見つけられませんでした。一つの可能性としては、(デフォルトで有効になっている) pam_env PAM モジュールを使用して、
~/.pam_environment
に以下のように記述することですBASH_ENV=./.environ # not a typo; it needs to be a path, but ~ won't work
そして、もちろん
~/.environ
をunset BASH_ENV
に更新する
結論は?貝殻は苦痛だ環境変数は苦痛です。ディストリビューション固有のコンパイル時オプションは非常に厄介です
58 community wiki 2014-07-29
このShreevatsaRによる優れたブログ記事を見てみてください。ここでは抜粋していますが、ブログ記事に行くと、”ログインシェル “のような用語の説明、フローチャート、Zshの同様のテーブルが含まれています
Bashの場合、以下のように動作します。適当なカラムを読み下す。Aを実行し、次にBを実行し、次にCを実行する。B1,B2,B3は、見つかったファイルの最初のものだけを実行することを意味します
+----------------+-----------+-----------+------+
| |Interactive|Interactive|Script|
| |login |non-login | |
+----------------+-----------+-----------+------+
|/etc/profile | A | | |
+----------------+-----------+-----------+------+
|/etc/bash.bashrc| | A | |
+----------------+-----------+-----------+------+
|~/.bashrc | | B | |
+----------------+-----------+-----------+------+
|~/.bash_profile | B1 | | |
+----------------+-----------+-----------+------+
|~/.bash_login | B2 | | |
+----------------+-----------+-----------+------+
|~/.profile | B3 | | |
+----------------+-----------+-----------+------+
|BASH_ENV | | | A |
+----------------+-----------+-----------+------+
| | | | |
+----------------+-----------+-----------+------+
| | | | |
+----------------+-----------+-----------+------+
|~/.bash_logout | C | | |
+----------------+-----------+-----------+------+
38 Flimm 2014-07-29
私の「総合的な」ガイドラインを提供します
.bash_profile
と.profile
は、.bashrc
が存在する場合には、[ -r $HOME/.bashrc ] && source $HOME/.bashrc
などを使って.bashrc
をロードするようにします- 他のものは全て
.bashrc
に入れてください - Stop worrying.
- 4年に1度かそこらで 10分かけてこの質問を調べて 諦める前に “心配しない “に戻るんだ
EDIT: 誰もがそれを信じたいと思っている場合に備えて、”包括的な “に恐怖の引用符を追加しました。)
23 Mechanical Fish 2014-07-29
私はこれを解明しようとすることを諦めて、一つのスクリプト(~/.shell-setup
)を作り、他のすべてのスクリプトをソースにしました
このアプローチでは、~/.shell-setup
が2つの特徴を持つことが必要です
- 繰り返しソースされても一度だけ実行する(インクルードガードを使用する)
- 不要な出力を発生させない(出力がOKの場合は検出)
#1 はかなり標準的なものですが、シェルスクリプトではあまり使われていないかもしれません
#2はもっと厄介です。私がbashで使っているのはこんな感じです
if [ "" == "$BASH_EXECUTION_STRING" -a "" == "$DESKTOP_SESSION" ]; then
echo "Hello user!" # ... etc
fi
残念ながら、どのようにしてそれを思いついたのか、対話型シェルの検出が不十分だった理由は覚えていません
1 ShadSterling 2014-07-31
すべてを.bashrc
に入れて、.bashrc
を.profile
からソースにする
bash の man ページから (OS X 10.9 の場合)
ログインシェルではない対話型シェルが起動されると、bash は ~/.bashrc ファイルが存在する場合には ~/.bashrc からコマンドを読み込んで実行します。これは –norc オプションを使用することで禁止されます。 rcfile file オプションは、~/.bashrc の代わりにファイルからコマンドを読み込んで実行するように bash を強制します
上の文章のように、すべてを.bashrc
に入れているのはそのためです。しかし、ログインシェルを扱っている場合は少し挙動が異なります。もう一度、マンページから引用します
対話的なログインシェルとして、あるいは –login オプションを指定して非対話的なシェルとして bash が起動されると、まず /etc/profile ファイルが存在する場合には、/etc/profile からコマンドを読み込んで実行します。そのファイルを読んだ後、~/.bash_profile、~/.bash_login、~/.profile の順に探し、最初に存在して読めるものからコマンドを読み込んで実行します。シェルの起動時に –noprofile オプションを使用すると、この動作を抑制することができます
.profile
はログインシェル用に読み込まれますが、.bashrc
は読み込まれません。.bashrc
にあるものをすべて複製するのは良くないので、動作が一貫しているようにするためには .profile
でソースを作成する必要があります
ただし、.bashrc
を.profile
から無条件にソースにするのはやめましょう。詳細はコメントや他の回答をご覧ください
-2 mattr- 2014-07-29