Bashを使用するほとんどの* nix環境では、環境変数~/.bash_profile
またはユーザーローカルの同様のファイルを変更し、変更がセッションsource
に適用されるように変更されたファイルを変更します。
同様に、変更後にsource
ing を実行すると、/etc/profile
その変更が現在のセッションに適用されます。
/etc/profile
しかし、(またはその下のどこかに)定義された/etc/profile.d/
環境変数を変更する必要があり、システム内のすべてのユーザーのすべてのセッションで変更がすぐに表示されることを望んでいるとします。システムを再起動せずにこれを達成するにはどうすればよいですか?
答え1
ログインしたすべてのユーザーを強制的にログオフして再度ログインすることができます(そして/ etc / profileを使用して、シェルで開始されたすべてのデーモンを終了して再起動します)。再起動は必要ありません。
それ以外はできません。
source /etc/profile
あなたができることは、新しい定義が必要な各シェルセッションから別々に/ etc / profileをインポートすることです...しかし、これは実際に実行または使用できるシェルにのみ影響します. /etc/profile
。たとえば、環境Aなど、既存のシェルを直接変更することはできません。すでに実行中のプロセス(例:実行中のXセッション)
サブプロセスできない親プロセスの環境を変更します。とにかく直接的ではありません(親プロセスできる自分の環境を変えることを含め、子どもが行うことを観察し、それに応じて行動します。しかし、これはまったく異なるものであり、親プロセスにプログラムする必要があります。)
答え2
実際にはそうする必要はありません。
その理由は、環境変数が実行時に(コマンドライン引数と同じ方法で)プログラムに渡されますが、その後はプロセスメモリのどこかにあるテーブルにすぎないからです。通常、外部または他のプロセスでは変更できません。あなたはその人がどこにいるのかわかりません。。
environ
Cライブラリは、まとめて「環境」と呼ばれる値を指すポインタのリストを指すポインタという名前を保持します。プログラムの存続期間中にテーブルの位置を再割り当てする必要がある場合、テーブルの位置は変更される可能性があり、値の位置も同様に変更されます。
ポインタ自体はプログラムの実行中に同じ位置にあるenviron
ため、ポインタを探す限り合理的に値をハッキングできます。アドレス空間レイアウトのランダム化などの操作により、異なるプログラム呼び出しで別の場所にある可能性があります。これを見つけてプログラムのメモリを変更しても、プログラムが値(またはそのポインタ)を他の場所にコピーして使用したかどうかはわかりません。同様の設定ファイルの内容がプログラムメモリの1つの場所にコピーされます。
execve()
システム・コール・レベルでは、環境値はシステム・コールの引数として明示的に渡されなければならず、そこに渡された表は何とも関係がある必要がないため、プログラムの実行中に環境は自動的にコピーされません。実行プロセスはそれを呼び出しますenviron
。
これはすべて、Linuxに表示される内容が/proc/$pid/environ
プログラムのシステムコールによって返される内容と一致しない可能性があることを意味します。getenv()
(ファイルには、プログラムの実行中に値を渡すために使用されるメモリ領域が表示されているようです。)「環境」が特別なデータ構造であるという発想は完全に正しくありません。
実行中のプログラムの構成を変更するには、プログラム自体のサポートが必要であり、プログラムはどこかで構成を再ロードできる必要があります。または、少なくとも親からの再読み込みをサポートするか、それ構成してから、サブプロセスを再起動して別の環境変数セットを渡します。