更改正在运行的进程的环境

Mar*_*cos 28 environment-variables proc

怎么可能改变env已经运行的进程中的某些变量,例如通过/proc/PID/environ?那个“文件”是read-only.

需要更改或取消设置长时间运行的批处理作业的 DISPLAY 变量而不终止它。

Mat*_*Mat 27

如果没有令人讨厌的黑客攻击,您就无法做到这一点 - 没有用于此的 API,无法通知进程其环境已更改(因为无论如何这都不可能)。
即使您确实设法做到了这一点,也无法确保它会产生任何影响 - 该过程很可能已经缓存了您尝试戳的环境变量(因为应该没有任何东西能够改变它) )。

如果您真的想这样做,并准备在出现问题时收拾残局,您可以使用调试器。例如,参见 Stack Overflow 问题:
Is there a way to change another process's environment variables?

本质上:

(gdb) attach process_id
(gdb) call putenv ("DISPLAY=your.new:value")
(gdb) detach
Run Code Online (Sandbox Code Playgroud)

您可以尝试调用的其他可能函数是setenvunsetenv

请务必记住,如果您的目标进程对其环境块做了“有趣”的事情,这可能不起作用,或者会产生可怕的后果。请先在非关键过程中对其进行测试,但要确保这些测试过程尽可能地反映您要尝试的过程。

  • 是的,我意识到这有点像黑客攻击,有风险,并且由于您提到的原因无法保证。(我访问这个组的部分原因是因为我似乎无法找到这种非常规的需求。)在这种情况下,将 DISPLAY 设置为垃圾或空只会解决烦恼和延迟(网络上不必要的频繁截图,如果他们失败了)。由于孩子复制父母,我只需要修改父环境。在我的批处理作业中,许多新的子进程正在生成并快速退出;那些事。我认为调试器可以做到这一点,谢谢——我可以将它包装到一个 shell 函数中。 (3认同)

小智 5

如果我将 gdb 附加到当前 shell 并尝试设置 env 变量,它会保持不变(或不存在):

$] sudo gdb -p $$
(gdb) call putenv("TEST=1234")
$1 = 0
(gdb) call (char*) getenv("TEST")
$2 = 0x0
(gdb) detach
(gdb) quit
$] echo "TEST=$TEST"
TEST=
Run Code Online (Sandbox Code Playgroud)

我发现putenv不起作用,但setenv可以:

$] sudo gdb -p $$
(gdb) call (int) setenv("TEST", "1234", 1)
$1 = 0
(gdb) call (char*) getenv("TEST")
$2 = 0x55f19ff5edc0 "1234"
(gdb) detach
(gdb) quit
$] echo "TEST=$TEST"
TEST=1234
Run Code Online (Sandbox Code Playgroud)