質問はそれをすべて言います。現在、Arch Linuxと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
_の主な制限は、複雑なシェル構文ではなく、単純な割り当てのみを配置できることです。このファイルの構文は次のとおりです。
export
と1つのスペースで開始できます(タブではなく、図を参照)。VAR=VALUE
_である必要があります。VARは文字、数字、およびアンダースコアで構成されます。#
_はコメントを開始します。値に含めることはできません。'
_または_"
_で始まり、同じ引用符がもう1つ含まれている場合、VARは引用符の間の文字列に設定されます(2番目の引用符以降は無視されます)。それ以外の場合、VARは_=
_記号の後の文字列に設定されます。=
_がない場合、変数は環境から削除されます。つまり、_~/.pam_environment
_は、さまざまな状況で機能します。欠点としては、変数の値を別の変数に基づいて(PATHにディレクトリを追加するなど)、コマンドの出力を使用する(たとえば、ディレクトリまたはプログラムが存在するかどうかをテストする)などの動的な設定を行うことはできません。文字(_#'"
_、改行)を値に入れることは不可能または面倒です。
~/.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_login
_ではなく_~/.bash_profile
_または_~/.profile
_が存在する場合はそれらを読み取ります。また、bashは、インタラクティブであっても、ログインシェルで_~/.bashrc
_を読み取りません。これらの癖を覚える必要がないようにするには、次の2行で_~/.bash_profile
_を作成します。
_. ~/.profile
case $- in *i*) . ~/.bashrc;; esac
_
参照 bashを使用して環境変数を設定するには、どの設定ファイルを使用する必要がありますか?
Zshは_~/.zprofile
_および_~/.zlogin
_を読み取りますが、_~/.profile
_は読み取りません。 Zshの構文はshとは異なりますが、shエミュレーションモードでは_~/.profile
_を読み取ることができます。これを_~/.zprofile
_に使用できます:
_emulate sh -c '. ~/.profile'
_
ログインシェルとして_/bin/sh
_を使用し、インタラクティブシェルとしてのみお気に入りのシェル(魚など)を使用する以外は、そこでできることは多くありません。それが私がzshで行うことです。 _~/.profile
_から別のシェルを呼び出す例については、上記を参照してください。
対話型シェルを経由せずにリモートコマンドを呼び出す場合、すべてのシェルが起動ファイルを読み取るわけではありません。
Kshは、渡した場合、ENV
変数で指定されたファイルを読み取ります。
Bashは、インタラクティブでない(!)であり、その親プロセスがrshd
またはsshd
である場合、_~/.bashrc
_を読み取ります。したがって、_~/.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
_を再度ソースすることに注意してください。
私が知る限り、環境変数の設定方法はディストリビューションやシェルにとらわれない標準が存在しません。
最も一般的で事実上の標準は/etc/profile
と~/.profile
のようです。 2番目に一般的なのは、/etc/environment
と~/.pam_environment
のようです。
私が見つけたすべてのドキュメントもすでに見つけたようです。私は他の読者のためにとにかくそれらをここにリストします。
/etc/profile
および~/.profile
( link )を推奨しています。/etc/environment
および~/.pam_environment
( link )を推奨しています。/etc/profile
および/etc/environment
( link )について言及しています。おまけ:debianでの/etc/environment
の使用や誤用について質問するテキスト( link 、最終更新2008)。
次のスクリプト〜/ bin/agnostic_setenvを追加しました:
#!/bin/csh -f
set args = ($*)
if ($#args == 1) then
echo "export $args[1]="
exit 0
endif
if ($#args == 2) then
if ("$args[1]" =~ *csh*) then
echo "setenv $args[2]"
exit 0
else
echo "export $args[1]=$args[2]"
exit 0
endif
endif
echo "setenv $args[2] $args[3]"
そして〜/ .Perl-homedirで私は使用します:
eval `${HOME}/bin/agnostic_setenv $Shell Perl_HOMEDIR 0`
Agnostic_unsetenvの類似スクリプト:
#!/bin/csh -f
set args = ($*)
if ($#args == 1) then
echo "export $args[1]"
exit 0
endif
echo "unsetenv $args[2]"
exit 0