无法访问子流程[重复项]中的环境变量

问题描述 投票:0回答:1

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

最后一行是subprocess.communicate()调用返回的标准输出。而不是返回env变量的实际值,而是按原样返回echo语句。

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

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

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

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

当我更改电话来自

Popen(["/bin/echo", "$TEST_VAR"], stdout=PIPE, stderr=PIPE, env=curenv, shell=True)

to

Popen(["/bin/echo$TEST_VAR"], stdout=PIPE, stderr=PIPE, env=curenv, shell=True)

我能够获得变量替换。

python python-2.7 subprocess environment-variables
1个回答
0
投票

$VAR_NAME语法可以通过执行等效语句的UNIX Shell进行识别和扩展。不是正在运行的程序。您正在将$VAR_NAME字符串文字直接传递给echo程序。就像您问的那样,它回显了该文本。如果您想执行类似的操作,则应在shell=True的调用中包含subprocess.Popen()。但是,这样做会产生很多问题。其中大多数是安全漏洞。如果您关心软件安全性,则应避免这样做。

© www.soinside.com 2019 - 2024. All rights reserved.