Unix で、あるプロセスが別のプロセスの環境変数を変更できる方法はありますか (それらがすべて同じユーザーによって実行されていると仮定して)? 一般的な解決策が最善ですが、そうでない場合、一方が他方の子であるという特定のケースはどうでしょうか?
編集:gdb経由はどうですか?
Unix で、あるプロセスが別のプロセスの環境変数を変更できる方法はありますか (それらがすべて同じユーザーによって実行されていると仮定して)? 一般的な解決策が最善ですが、そうでない場合、一方が他方の子であるという特定のケースはどうでしょうか?
編集:gdb経由はどうですか?
gdb 経由:
(gdb) attach process_id
(gdb) call putenv ("env_var_name=env_var_value")
(gdb) detach
これは非常に厄介なハックであり、もちろん、デバッグ シナリオのコンテキストでのみ実行する必要があります。
You probably can do it technically (see other answers), but it might not help you.
Most programs will expect that env vars cannot be changed from the outside after startup, hence most will probably just read the vars they are interested in at startup and initialize based on that. So changing them afterwards will not make a difference, since the program will never re-read them.
If you posted this as a concrete problem, you should probably take a different approach. If it was just out of curiosity: Nice question :-).
実質的に、いいえ。十分な特権 (root など) を持っていて、/dev/kmem (カーネル メモリ) をいじり、プロセスの環境に変更を加え、その後プロセスが実際に環境変数を再参照した場合 (つまり、プロセス環境変数のコピーをまだ取得しておらず、そのコピーだけを使用していませんでした)、もしあなたが幸運で賢く、風が正しい方向に吹いていて、月の満ち欠けが正しかったとしたら、おそらく、何かを達成するかもしれません。
私はそれを行うためのかなり工夫された方法を考えることができました、そしてそれは恣意的なプロセスのために働きません。
'char*getenv'を実装する独自の共有ライブラリを作成するとします。次に、「LD_PRELOAD」または「LD_LIBRARY_PATH」envを設定します。varsを使用すると、共有ライブラリがプリロードされた状態で両方のプロセスが実行されます。
このようにして、基本的に「getenv」関数のコードを制御できます。次に、あらゆる種類の厄介なトリックを行うことができます。'getenv'は、env変数の代替値について、外部構成ファイルまたはSHMセグメントを参照できます。または、要求された値に対して正規表現の検索/置換を行うこともできます。または ...
ダイナミックリンカ(ld-linux.so)を書き直す以外に、実行中の任意のプロセス(rootであっても)に対してこれを行う簡単な方法は考えられません。
ジェリー・ピークの引用:
老犬に新しい技を教えることはできません。
あなたができる唯一のことは、開始する前に子プロセスの環境変数を変更することです: 申し訳ありませんが、親環境のコピーを取得します。
詳細については、 http://www.unix.com.ua/orelly/unix/upt/ch06_02.htmを参照してください。
/proc の使用に関する回答へのコメントです。Linux では /proc がサポートされていますが、動作しません。rootであってもファイルを変更することはできません。完全に読み取り専用です。/proc/${pid}/environ
または、新しいプロセスの構成ファイルを更新するプロセスを取得してから、次のいずれかを行います。
私が知る限りではありません。実際には、IPC メソッド (共有メモリ、セマフォ、ソケットなど) の 1 つを呼び出すあるプロセスから別のプロセスに通信しようとしています。これらの方法のいずれかでデータを受信すると、環境変数を設定したり、他のアクションをより直接的に実行したりできます。
UNIXはプロセス間通信でいっぱいです。ターゲットインスタンスにいくつかあるかどうかを確認します。Dbusは「デスクトップ」IPCの標準になりつつあります。
luaコードのDbus「送信者」であるawesome-clientを使用して、Awesomeウィンドウマネージャー内の環境変数を変更します。
Not a direct answer but... Raymond Chen had a [Windows-based] rationale around this only the other day :-
... Although there are certainly unsupported ways of doing it or ways that work with the assistance of a debugger, there’s nothing that is supported for programmatic access to another process’s command line, at least nothing provided by the kernel. ...
That there isn’t is a consequence of the principle of not keeping track of information which you don’t need. The kernel has no need to obtain the command line of another process. It takes the command line passed to the
CreateProcess
function and copies it into the address space of the process being launched, in a location where theGetCommandLine
function can retrieve it. Once the process can access its own command line, the kernel’s responsibilities are done.Since the command line is copied into the process’s address space, the process might even write to the memory that holds the command line and modify it. If that happens, then the original command line is lost forever; the only known copy got overwritten.
In other words, any such kernel facilities would be
However the most likely reason is simply that there's limited use cases for such a facility.
Unix が /proc ファイルシステムをサポートしている場合、env を読み取るのは簡単です。環境、コマンドライン、および所有するプロセスの他の多くの属性を読み取ることができます。それを変更する...まあ、方法を考えることができますが、それは悪い考えです.
より一般的なケース...わかりませんが、ポータブルな答えがあるとは思えません。
(編集: 私の元の回答では、OP が env を変更するのではなく、読み取りたいと想定していました)