113

Unix で、あるプロセスが別のプロセスの環境変数を変更できる方法はありますか (それらがすべて同じユーザーによって実行されていると仮定して)? 一般的な解決策が最善ですが、そうでない場合、一方が他方の子であるという特定のケースはどうでしょうか?

編集:gdb経由はどうですか?

4

11 に答える 11

152

gdb 経由:

(gdb) attach process_id

(gdb) call putenv ("env_var_name=env_var_value")

(gdb) detach

これは非常に厄介なハックであり、もちろん、デバッグ シナリオのコンテキストでのみ実行する必要があります。

于 2008-10-17T04:19:02.683 に答える
22

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 :-).

于 2009-02-27T09:43:54.353 に答える
14

実質的に、いいえ。十分な特権 (root など) を持っていて、/dev/kmem (カーネル メモリ) をいじり、プロセスの環境に変更を加え、その後プロセスが実際に環境変数を再参照した場合 (つまり、プロセス環境変数のコピーをまだ取得しておらず、そのコピーだけを使用していませんでした)、もしあなたが幸運で賢く、風が正しい方向に吹いていて、月の満ち欠けが正しかったとしたら、おそらく、何かを達成するかもしれません。

于 2008-10-16T17:50:38.927 に答える
7

私はそれを行うためのかなり工夫された方法を考えることができました、そしてそれは恣意的なプロセスのために働きません。

'char*getenv'を実装する独自の共有ライブラリを作成するとします。次に、「LD_PRELOAD」または「LD_LIBRARY_PATH」envを設定します。varsを使用すると、共有ライブラリがプリロードされた状態で両方のプロセスが実行されます。

このようにして、基本的に「getenv」関数のコードを制御できます。次に、あらゆる種類の厄介なトリックを行うことができます。'getenv'は、env変数の代替値について、外部構成ファイルまたはSHMセグメントを参照できます。または、要求された値に対して正規表現の検索/置換を行うこともできます。または ...

ダイナミックリンカ(ld-linux.so)を書き直す以外に、実行中の任意のプロセス(rootであっても)に対してこれを行う簡単な方法は考えられません。

于 2008-10-15T15:54:14.077 に答える
7

ジェリー・ピークの引用:

老犬に新しい技を教えることはできません。

あなたができる唯一のことは、開始するに子プロセスの環境変数を変更することです: 申し訳ありませんが、親環境のコピーを取得します。

詳細については、 http://www.unix.com.ua/orelly/unix/upt/ch06_02.htmを参照してください。

/proc の使用に関する回答へのコメントです。Linux では /proc がサポートされていますが、動作しません。rootであってもファイルを変更することはできません。完全に読み取り専用です。/proc/${pid}/environ

于 2008-10-15T15:07:49.443 に答える
3

または、新しいプロセスの構成ファイルを更新するプロセスを取得してから、次のいずれかを行います。

  • 新しいプロセスで kill -HUP を実行して、更新された構成ファイルを再読み込みするか、または
  • プロセスで構成ファイルの更新を時々チェックするようにします。変更が見つかった場合は、構成ファイルを再度読み取ります。
于 2008-10-15T15:10:58.517 に答える
2

私が知る限りではありません。実際には、IPC メソッド (共有メモリ、セマフォ、ソケットなど) の 1 つを呼び出すあるプロセスから別のプロセスに通信しようとしています。これらの方法のいずれかでデータを受信すると、環境変数を設定したり、他のアクションをより直接的に実行したりできます。

于 2008-10-15T15:10:24.977 に答える
1

UNIXはプロセス間通信でいっぱいです。ターゲットインスタンスにいくつかあるかどうかを確認します。Dbusは「デスクトップ」IPCの標準になりつつあります。

luaコードのDbus「送信者」であるawesome-clientを使用して、Awesomeウィンドウマネージャー内の環境変数を変更します。

于 2011-05-31T12:52:59.950 に答える
1

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 the GetCommandLine 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

  • difficult to implement
  • potentially a security concern

However the most likely reason is simply that there's limited use cases for such a facility.

于 2009-02-27T09:50:51.200 に答える
1

Unix が /proc ファイルシステムをサポートしている場合、env を読み取るのは簡単です。環境、コマンドライン、および所有するプロセスの他の多くの属性を読み取ることができます。それを変更する...まあ、方法を考えることができますが、それは悪い考えです.

より一般的なケース...わかりませんが、ポータブルな答えがあるとは思えません。

(編集: 私の元の回答では、OP が env を変更するのではなく、読み取りたいと想定していました)

于 2008-10-15T15:05:36.390 に答える