在Python中模拟Bash“源”

我有一个脚本,看起来像这样:


export foo=/tmp/foo                                          

export bar=/tmp/bar

每次构建时,我都会运行“ source init_env”(其中init_env是上面的脚本)来设置一些变量。


为了在Python中完成同样的工作,我运行了这段代码,


reg = re.compile('export (?P<name>\w+)(\=(?P<value>.+))*')

for line in open(file):

    m = reg.match(line)

    if m:

        name = m.group('name')

        value = ''

        if m.group('value'):

            value = m.group('value')

        os.putenv(name, value)

但是后来有人决定将以下行添加到init_env文件中会很好:


export PATH="/foo/bar:/bar/foo:$PATH"     

显然我的Python脚本崩溃了。我可以修改Python脚本来处理这一行,但是稍后当有人想出要在init_env文件中使用的新功能时,它将中断。


问题是,是否有一种简单的方法来运行Bash命令并让其修改我的os.environ?


倚天杖
浏览 386回答 3
3回答

慕桂英4014372

您的方法存在的问题是您正在尝试解释bash脚本。首先,您只是尝试解释导出语句。然后您会发现人们正在使用变量扩展。以后人们将条件文件放入他们的文件中,或处理替代文件。最后,您将获得功能齐全的bash脚本解释器,其中包含大量错误。不要那样做让Bash为您解释文件,然后收集结果。您可以这样做:#! /usr/bin/env pythonimport osimport pprintimport shleximport subprocesscommand = shlex.split("env -i bash -c 'source init_env && env'")proc = subprocess.Popen(command, stdout = subprocess.PIPE)for line in proc.stdout:&nbsp; (key, _, value) = line.partition("=")&nbsp; os.environ[key] = valueproc.communicate()pprint.pprint(dict(os.environ))确保处理错误,以防bash失败source init_env,bash本身无法执行,子进程无法执行bash或任何其他错误。将env -i在命令行的开始创造一个清洁的环境。这意味着您只能从中获取环境变量init_env。如果要继承的系统环境,请省略env -i。请阅读有关子流程的文档,以获取更多详细信息。注意:这将仅捕获使用export语句设置的变量,因为env仅打印导出的变量。请享用。请注意,Python文档指出,如果要操作环境,则应os.environ直接操作而不是使用os.putenv()。我认为是一个错误,但我离题了。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python