如何在subprocess.Popen()中使用现有的Environment变量

use*_*078 3 python subprocess

情境

在我的python脚本中,我需要使用x个可执行文件期望的命令行参数,将可执行文件作为子进程运行。

例:

  • EG 1:myexec.sh param1 param2
  • EG 2:myexec.sh param1 $ MYPARAMVAL

可执行文件和参数未知,因为它们是在运行时从外部源(xml配置)中配置和检索的。

当参数是一个已知值(EG 1)并已配置时,我的代码正在工作,但是期望参数可以是环境变量并如此配置,应在运行时解释该参数。(EG 2)

在下面的示例中,我使用echo代替myexec.sh来演示该方案。这被简化以演示问题。“ cmdlst”是从配置文件构建的,该文件可以是具有任意数量的参数和值(可以是值或环境变量)的任何脚本。

test1.py

import subprocess
import os

cmdlst = ['echo','param1','param2']

try:
    proc = subprocess.Popen(cmdlst,stdout=subprocess.PIPE)
    jobpid = proc.pid
    stdout_value, stderr_value = proc.communicate()
except (OSError, subprocess.CalledProcessError) as err:
    raise

print stdout_value
Run Code Online (Sandbox Code Playgroud)

结果测试1

python test1.py

-> param1 param2

test2.py

import subprocess
import os

cmdlst = ['echo','param1','$PARAM']

try:
    proc = subprocess.Popen(cmdlst,stdout=subprocess.PIPE)
    jobpid = proc.pid
    stdout_value, stderr_value = proc.communicate()
except (OSError, subprocess.CalledProcessError) as err:
    raise

print stdout_value
Run Code Online (Sandbox Code Playgroud)

结果测试2

导出PARAM = param2 echo $ PARAM

-> param2 python test2.py

-> param1 $ PARAM

考虑到$ PARAM仅在运行时才知道,并且需要从当前环境中检索,因此我要求Test 2产生与Test 1相同的结果。

我欢迎您的建议。

not*_*ess 5

你可以这样做:

cmdlist = ['echo','param',os.environ["PARAM"]]
Run Code Online (Sandbox Code Playgroud)

或者:

cmdlist = ['echo','param1','$PARAM']
proc = subprocess.Popen(cmdlist,stdout=subprocess.PIPE, env={'PARAM':os.environ['PARAM'])
Run Code Online (Sandbox Code Playgroud)


Bre*_*bel 5

如果要让shell扩展环境变量,则必须设置 shell=True

subprocess.Popen('echo param1 $PARAM', shell=True, stdout=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)

或者,您可以在构造命令时自行查询环境变量,然后无需进行外壳扩展

subprocess.Popen(['echo', 'param1', os.environ['PARAM']], stdout=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)