Python 无法访问子流程内的环境变量

Python 无法访问子流程内的环境变量,python,python-2.7,subprocess,environment-variables,Python,Python 2.7,Subprocess,Environment Variables,python版本:2.7.12 环境:MacOS+virtualenv 我使用以下代码显示传递给子流程的环境变量 from subprocess import Popen, PIPE import os def run_baelish(svc, cfg, dest_dir="/config", cmd=["baelish-client"]): """ Executes baelish command at given directory """ che

python版本:2.7.12 环境:MacOS+virtualenv

我使用以下代码显示传递给子流程的环境变量

from subprocess import Popen, PIPE
import os


def run_baelish(svc, cfg, dest_dir="/config", cmd=["baelish-client"]):
    """
        Executes baelish command at given directory
    """
    chenv = os.environ.copy()
    chenv["TEST_VAR"] = "test"
    print(chenv["TEST_VAR"])
    try:
        print(cmd)
        p = Popen(cmd, stdout=PIPE, stderr=PIPE, env=chenv)
        (out, err) = p.communicate()
        if out is not None:
            print(out)
        if err is not None:
            print(err)
        return p.returncode
    except OSError as oe:
        print("baelish-client executable not found")
        print(oe)
        return oe.errno
    except ValueError as ve:
        print("Invalid arguments passed to baelish-client")
        print(ve)
        return 3
# end of run baelish function
我从测试代码中调用此函数,如下所示:

import unittest
import os
from helper.operations import run_baelish

class TestBaelishRun(unittest.TestCase):
    def setUp(self):
        pass

   def testSuccess(self):
        run_baelish("monolith", "master", "", cmd=["echo", "$TEST_VAR"])

# End of class TestBaelish Run
运行测试后,我得到以下结果

.test
['echo', '$TEST_VAR']
$TEST_VAR
最后一行是
子流程.communicate()调用返回的标准输出。它不返回env变量的实际值,而是按原样返回echo语句

编辑:我已经尝试设置
shell=True
选项。即使这样也没有给我变量替换

我试图在子流程中打印整个
env
,它显示了变量TEST\u VAR集。所以我猜这是子流程内部bash变量外推的问题,因为它不在任何shell下运行

我很好奇它是否会影响任何依赖于env变量的cmd。我会再进行一些测试

更新: 我要把这张票作为副本关闭。 问题是我如何将命令传递给
Popen

当我换电话的时候 从


我能够得到变量替换。

unixshell执行等效语句时会识别并扩展
$VAR\u NAME
语法。不是正在运行的程序。您正在将
$VAR_NAME
字符串文本直接传递给
echo
程序。正如你所问的,它与那篇文章相呼应。如果要执行类似的操作,应该在调用
subprocess.Popen()
时包含
shell=True
。但是,这样做会产生大量问题;其中大部分是安全漏洞。如果您关心软件安全,那么应该避免这样做。

cmd=[“echo”,“$TEST\u VAR”]
不是有效的测试。它根本不会扩展
$TEST\u VAR
。运行
cmd=['sh','-c',echo“$TEST\u VAR”]
…这与在shell上运行
echo'$TEST\u VAR'
是一样的<代码>$TEST\u VAR
作为文本数据传递,而不是作为扩展进行分析。是。是的。我所犯的错误是将命令作为列表而不是字符串传递。这是有效的``Popen([“/bin/echo$TEST\u VAR”]、env=d)``这不是有效的``Popen([“/bin/echo”、“$TEST\u VAR”]、env=d)``
Popen([“/bin/echo$TEST\u VAR”]、env=d)
只有在您还添加了
shell=True
,这将
['sh'、'-c']
作为前两个列表元素,使其与我在第一次评论中的建议完全相同。您可以在Python源代码中看到您自己,但并不完全相同,因为您的引用是错误的,因此当您使用
echo$TEST\u VAR
而不是
echo“$TEST\u VAR”
时,您会遇到中讨论的错误。
Popen(["/bin/echo", "$TEST_VAR"], stdout=PIPE, stderr=PIPE, env=curenv, shell=True)
Popen(["/bin/echo$TEST_VAR"], stdout=PIPE, stderr=PIPE, env=curenv, shell=True)