【发布时间】:2013-03-25 19:22:49
【问题描述】:
使用 Python,我如何使用修改后的环境变量运行子进程并获取其 PID?我假设 subprocess.Popen() 是在正确的轨道上......
在 shell (bash) 中,我会这样做:
MY_ENV_VAR=value ./program_name arg1 arg2 etc &
这会在后台运行program_name,传入“arg1”、“arg2”和“etc”,并使用修改后的环境变量“MY_ENV_VAR”,其值为“value”。程序program_name 要求将环境变量MY_ENV_VAR 设置为正确的值。
如何在 Python 中做同样的事情?我绝对需要进程的PID。 (我的目的是保持 python 脚本运行并检查program_name 在此期间正在做的一些事情,我需要进程 ID 以确保它仍在运行。)
我试过了:
proc = subprocess.Popen(['MY_ENV_VAR=value', './program_name', 'arg1', 'arg2', 'etc'])
当然,它希望第一项是程序,而不是环境变量。
也试过了:
environ = dict(os.environ)
environ['MY_ENV_VAR'] = 'value'
proc = subprocess.Popen(['./program_name', 'arg1', 'arg2', 'etc', env=environ])
关闭,我想,但没有雪茄。同样,这个:
environ = dict(os.environ)
environ['MY_ENV_VAR'] = 'value'
proc = subprocess.Popen(['echo', '$MY_ENV_VAR'], env=environ)
这在字面上与“$MY_ENV_VAR”相呼应,我想是因为没有外壳可以解释它。好的,所以我尝试上面的方法,但改用这一行:
proc = subprocess.Popen(['echo', '$MY_ENV_VAR'], env=environ, shell=True)
这很好,很漂亮,除了回显的值是空白的(显然不存在)。即使它确实有效,我也会得到 shell 的 PID,而不是我尝试启动的实际进程。
我需要使用自定义环境变量启动一个进程并获取它的 PID(不是 shell 的 PID)。想法?
【问题讨论】:
-
您真的确定您的实际用例需要一个外壳吗?当然,您需要它用于 echo 测试用例,但在调用实际程序时通常不会/不应该使用它。
-
@CharlesDuffy 我只需要 shell,只要设置/传递该进程的环境变量即可。如果我不需要外壳,我宁愿不使用它。 (但我确实需要将参数传递给程序并让它在后台运行。)
-
环境变量被传递给
proc = subprocess.Popen(['echo', '$MY_ENV_VAR'], env=environ)示例中的子进程;该子进程根本不会做任何事情来向您表明它们是,因为 echo 从不查看它的环境。请改用subprocess.Popen(['env'], env=environ)。 -
@CharlesDuffy D'oh!而已。你和 abarnet 几乎是同时给我的。
-
顺便说一下,如果您在使用
shell=True时需要“真实程序的”PID(同样,除非您真的知道自己在做什么,否则永远不要使用它'正在做),您可以让 shell 脚本使用exec调用最终命令。对于这个例子:exec echo "$MY_ENV_VAR";这样做会导致 echo 命令替换正在运行的 shell 的进程,继承它的 PID。
标签: python subprocess popen pid