python - 如何使用自定义环境变量通过 subprocess.Popen 获取 PID?

标签 python subprocess popen pid

使用 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”,我想是因为没有 shell 来解释它。好的,所以我尝试上面的方法,但改用这一行:

proc = subprocess.Popen(['echo', '$MY_ENV_VAR'], env=environ, shell=True)

这很好,很花哨,只是回显的值是空白的(显然不存在)。即使它确实有效,我也会得到 shell 的 PID,而不是我尝试启动的实际进程。

我需要启动一个带有自定义环境变量的进程并获取它的 PID(不是 shell 的 PID)。想法?

最佳答案

您的上一个版本非常接近,但还不够。

您不希望 $MY_ENV_VAR 成为 echo 的参数。 echo 程序将在其环境中包含 MY_ENV_VAR,但 echo 不进行任何环境变量扩展。您需要在它到达 echo 之前由 shell 对其进行扩展。

这实际上可能与您的真实测试用例无关。您已经在所有测试中为子进程获取环境变量,只是 echo 不对该环境变量做任何事情。如果你的真实程序只需要设置环境变量,你就完成了:

proc = subprocess.Popen(['./program_name', 'arg1', 'arg2', 'etc'], env=environ)

但如果您的程序需要替换,例如echo,那么您必须在参数通过之前将其替换为参数到你的程序。

最简单的方法是只给 shell 一个命令行而不是参数列表:

proc = subprocess.Popen('echo "$MY_ENV_VAR"', env=environ, shell=True)

人们会告诉您永远不要在 subprocess 中使用命令字符串——但这样做的原因是您总是希望防止 shell 以某种方式扩展变量等可能不安全/等等。在极少数情况下,当您希望 shell 执行其 shelly 操作时,您需要命令字符串。

当然,如果您使用 shell,在大多数平台上,您将最终获得 shell 的 PID 而不是实际程序的 PID。如果不进行一些特定于平台的挖掘以枚举 shell 的子级(或将整个事情包装在一些简单的 sh 代码中,间接为您提供子级的 PID),就没有办法解决这个问题。外壳就是您正在运行的。

另一种方法是在 Python 中扩展变量,而不是让 shell 来做。那么您甚至不需要 shell:

proc = subprocess.Popen(['echo', os.path.expandvars('$MY_ENV_VAR')])

……或者,更简单地说:

proc = subprocess.Popen(['echo', os.environ['MY_ENV_VAR']])

关于python - 如何使用自定义环境变量通过 subprocess.Popen 获取 PID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15799012/

相关文章:

python - 努力在Python中显示阿拉伯语推文

python - 执行 docker exec 命令时 python 脚本的执行挂起

Python 和直接访问命令行实用程序 ifconfig、iwconfig 和 iw

python - 从 python 调用需要文件的 shell 脚本而不将文件写入磁盘

python-3.x - 往返 2 个 Python 子进程的循环管道

python - 如何获取每个嵌套列表的第三个元素,但如果第三个元素不存在则将其设置为 null?

python - 没有时间的python中的tail -f.sleep

python - for 循环有什么问题

Cygwin-尝试用C语言运行DOS命令

python - 删除列中包含特定子字符串的行