【问题标题】:Unable to access environment variables inside subprocess [duplicate]无法访问子进程内的环境变量[重复]
【发布时间】:2020-06-16 12:21:14
【问题描述】:

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 下运行。

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

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

当我改变我的电话时 来自

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)

我能够获得变量替换。

【问题讨论】:

  • cmd=["echo", "$TEST_VAR"] 不是有效的测试。它从不扩展$TEST_VAR。运行cmd=['sh', '-c', 'echo "$TEST_VAR"']
  • ...就像你在 shell 中运行 echo '$TEST_VAR' 一样; $TEST_VAR 作为文字数据传递,而不是作为扩展解析。
  • 是的。确实如此。我犯的错误是将命令作为列表而不是字符串传递。这可行 ``` Popen(["/bin/echo $TEST_VAR"], env=d) ``` 这不行 ``` Popen(["/bin/echo", "$TEST_VAR"], env= d) ```
  • Popen(["/bin/echo $TEST_VAR"], env=d) 仅在您还添加 shell=True 时才有效,这会将 ['sh', '-c'] 添加为前两个列表元素,使其与我在第一条评论中的建议完全相同。您可以在github.com/python/cpython/blob/master/Lib/… 的 Python 源代码中看到自己
  • 嗯,不是相当相同,因为你的引号是错误的,所以当你使用echo $TEST_VAR而不是echo "$TEST_VAR"时,你会遇到BashPitfalls #14中讨论的错误。

标签: python python-2.7 subprocess environment-variables


【解决方案1】:

$VAR_NAME 语法被执行等效语句的 UNIX shell 识别和扩展。不是正在运行的程序。您将$VAR_NAME 字符串文字直接传递给echo 程序。正如您所问的,这与该文本相呼应。如果你想做这样的事情,你应该在你的subprocess.Popen() 调用中包含shell=True。但是,这样做会产生大量问题;其中大部分是安全漏洞。如果您关心软件安全,则应避免这样做。

【讨论】:

    猜你喜欢
    • 2016-07-14
    • 2014-02-11
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 2023-01-08
    • 2016-12-26
    • 2018-03-17
    • 2021-05-05
    相关资源
    最近更新 更多