【问题标题】:Python work with parent shell environmentPython 与父 shell 环境一起工作
【发布时间】:2015-10-09 10:44:20
【问题描述】:

是否可以创建一个 shell 对象并在执行命令后不丢失数据的情况下对其进行操作?

from subprocess import *
sh.Popen('/bin/bash', stdout=PIPE)
sh.communicate('source /path/to/file/env.sh')
print os.getenv('ENV_VAR1')

ENV_VAR1 应该在采购/path/to/file/env.sh 之后可用,但它不是。 这部分代码没有按预期工作,我怎样才能让它工作?

这是另一个效果不佳的尝试

os.system('source env.sh; echo $ENV_VAR1') #Prints out correct value
os.system('echo $ENV_VAR1') #Prints nothing

【问题讨论】:

    标签: python linux shell


    【解决方案1】:

    这不是 Python 问题。环境变量仅对设置它们的进程和任何子进程可见。在这些示例中,您尝试在子级中设置环境变量并从父级访问它们,这根本行不通。

    如果您想将这些值传回给父级,则需要安排某种明确的通信(例如,让子级将值写入标准输出并从父级读取)。

    【讨论】:

    • OP 并没有说这是一个问题。看起来他/她需要一种方法来保存后续 shell 调用之间的上下文
    【解决方案2】:

    您可以echo $ENV_VAR1,并使用communicate 从标准输出返回结果:

    import subprocess
    proc = subprocess.Popen('source /path/to/file/env.sh; echo $ENV_VAR1', 
                            stdout=PIPE, shell=True)
    env_var1, err = proc.communicate()
    print(env_var1)
    

    另一种选择可能是使用Miki Tebeka's source function

    import subprocess
    import os
    
    def source(script, update=True):
        """
        source a file and return the environment as a dict.
        http://pythonwise.blogspot.fr/2010/04/sourcing-shell-script.html (Miki Tebeka)
        """
        proc = subprocess.Popen("source %s; env -0" % script, stdout=subprocess.PIPE, 
                                shell=True)
        output, err = proc.communicate()
        env = dict((line.split("=", 1) for line in output.split('\x00') if line))
        if update:
            os.environ.update(env)
        return env
    
    source('/path/to/env.sh')
    print(os.environ['ENV_VAR1'])
    

    如果/path/to/file/env.sh 包含

    ENV_VAR1=FOO
    export ENV_VAR1
    

    上面的脚本打印出来

    FOO
    

    以上,I made a small change 至 该函数使env 使用空字节(\x00)来分隔输出 线。这使得解析跨越多个名称/值对成为可能 行。

    【讨论】:

    • bash 的好解决方案,但不起作用的是源文件是tcsh 文件,proc.communicate() 返回空元组
    • 使用点(如. /path/to/env.sh)来获取文件是一种 bash 主义。我认为 bash 和 tcsh 都可以使用source /path/to/env.sh。我已经更改了上面的代码(在source 函数中)来解决这个问题。
    猜你喜欢
    • 2016-01-28
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    • 2017-10-14
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    • 2022-01-18
    相关资源
    最近更新 更多