質問はそれをすべて言います。私は現在ArchLinuxとzshを使用していますが、(少なくとも)VTとxtermの両方で機能し、ディストリビューションまたはシェルを切り替えても(できれば)引き続き機能するソリューションが必要です。
さまざまなディストリビューションのドキュメントで、この質問に対する非常に異なる回答を聞いたことがあります。 Ubuntuは「.pam_environmentを使用する」と言っています。 Archで彼らが推奨するものはあなたのシェルに依存すると思います。現在、すべてを.profileに配置していますが、シェルが何らかの理由でそれをソースしない場合(たとえば、.bash_profileが存在する場合はbash)、手動でソースすることでオーバーライドします。しかし、もっと良い方法があるはずです。
承認された回答:
残念ながら、環境変数を設定するための完全に移植可能な場所はありません。最も近い2つのファイルは、 ~/.profile
です。 、これは従来の場所であり、多くのセットアップですぐに使用できます。 ~/.pam_environment
、現代的でありふれた、しかし限られた選択肢。
~/.pam_environment
に何を入れるか
ファイル~/.pam_environment
PAMを使用し、このファイルが有効になっているすべてのログイン方法で読み取られます。これは、最近のほとんどのLinuxシステムを対象としています。
~/.pam_environment
の主な利点 これは、(有効になっている場合)ユーザーのシェルが開始する前に読み取られるため、セッションタイプ、ログインシェル、およびその他の複雑さに関係なく機能します。 su -c somecommand
などの非対話型ログインでも機能します およびssh somecommand
。
~/.pam_environment
の主な制限 複雑なシェル構文ではなく、単純な割り当てのみをそこに配置できるということです。このファイルの構文は次のとおりです。
- ファイルは1行ずつ解析されます。
- 各行の形式は
VAR=VALUE
である必要があります ここで、VARは文字、数字、およびアンダースコアで構成されます。代替形式VAR DEFAULT=value
${VAR}
を使用して環境変数を拡張できます 構文と特殊変数@{HOME}
および@{SHELL}
。 -
#
コメントを開始します。値に表示することはできません。 - VALUEが
"
で囲まれている場合 、次にVARが引用符の間の文字列に設定されます。 -
$
または@
リテラルの$
を挿入します または@
長い行は、で改行をエスケープすることで分割できます 。
-
=
などの構文エラーがある場合 または引用符で囲まれていない空白の場合、変数は環境から削除されます。
したがって、逆に、~/.pam_environment
さまざまな状況で機能します。欠点としては、コマンドの出力(たとえば、ディレクトリまたはプログラムが存在するかどうかをテストする)と一部の文字(#"
)を使用できません。 、改行)値を入力することは不可能または面倒です。
~/.profile
に何を入れるか
このファイルには、ポータブル(POSIX)sh構文が必要です。 kshまたはbash拡張機能(配列、[[ … ]]
のみを使用してください 、など)システムに/bin/sh
としてこれらのシェルがあることがわかっている場合 。
このファイルは自動化されたアプリケーションのスクリプトによって読み取られる可能性があるため、出力を生成するプログラムを呼び出したり、exec
を呼び出したりしないでください。 。テキストモードのログインでこれを実行する場合は、インタラクティブシェルに対してのみ実行してください。例:
case $- in *i*)
# Display a message if I have new mail
if mail -e; then echo 'You have new mail'; fi
# If zsh is available, and this looks like a text-mode login, run zsh
case "`ps $PPID` " in
*" login "*)
if type zsh >/dev/null 2>/dev/null; then exec zsh; fi;;
esac
esac
これは、/bin/sh
の使用例です。 ログインシェルとして、お気に入りのシェルに切り替えます。システム管理者が変更を拒否した場合に、ログインシェルとしてbashを使用する方法も参照してください
~/.profile
はいつですか 非グラフィカルログインで読まない?
異なるログインシェルは異なるファイルを読み取ります。
ログインシェルがbashの場合
Bashは~/.bash_login
を読み取ります または~/.bash_profile
~/.profile
の代わりに存在する場合 。また、bashは~/.bashrc
を読み取りません インタラクティブであっても、ログインシェルで。これらの癖を二度と覚える必要がないように、~/.bash_profile
を作成してください 次の2行で:
. ~/.profile
case $- in *i*) . ~/.bashrc;; esac
ログインシェルがzshの場合
Zshは~/.zprofile
を読み取ります および~/.zlogin
、ただし~/.profile
ではありません 。 Zshの構文はshとは異なりますが、~/.profile
を読み取ることができます。 エミュレーションモードで。これを~/.zprofile
に使用できます :
emulate sh -c '. ~/.profile'
ログインシェルが他のシェルの場合
/bin/sh
を使用する以外に、そこでできることはあまりありません。 ログインシェルとして、およびインタラクティブシェルとしてのみお気に入りのシェル(魚など)として。それが私がzshで行うことです。 ~/.profile
から別のシェルを呼び出す例については、上記を参照してください。 。
リモートコマンド
対話型シェルを経由せずにリモートコマンドを呼び出す場合、すべてのシェルがスタートアップファイルを読み取るわけではありません。
Kshは、ENV
で指定されたファイルを読み取ります あなたがそれを渡すことができれば、変数。
Bashは~/.bashrc
を読み取ります インタラクティブでない場合 (!)およびその親プロセスはrshd
と呼ばれます またはsshd
。したがって、~/.bashrc
を開始できます と
if [[ $- != *i* ]]; then
. ~/.profile
return
fi
Zshは常に~/.zshenv
を読み取ります それが始まるとき。他の変数を設定したサブシェルであっても、これはzshのすべてのインスタンスによって読み取られるため、注意して使用してください。 zshがログインシェルであり、リモートコマンドの変数のみを設定するために使用する場合は、ガードを使用します。~/.profile
に変数を設定します。 、MY_ENVIRONMENT_HAS_BEEN_SET=yes
など 、~/.profile
を読む前に、このガードを確認してください 。
if [[ -z $MY_ENVIRONMENT_HAS_BEEN_SET ]]; then emulate sh -c '~/.profile'; fi
グラフィカルログインの場合
多くのディストリビューション、ディスプレイマネージャー、デスクトップ環境では、~/.profile
を実行するように調整されています。 、起動スクリプトから明示的に取得するか、ログインシェルを実行します。
残念ながら、~/.profile
でdistro/DM/DEの組み合わせを処理する一般的な方法はありません。 読み取られません。
~/.xsession
で開始された従来のセッションを使用する場合 、これは環境変数を設定する必要がある場所です。 ~/.profile
を調達してください (つまり、. ~/.profile
)。一部の設定では、デスクトップ環境の起動スクリプトが~/.profile
をソースすることに注意してください。 もう一度。