为了账号安全,请及时绑定邮箱和手机立即绑定

在Python中模拟Bash“源”

在Python中模拟Bash“源”

倚天杖 2019-11-12 10:19:21
我有一个脚本,看起来像这样: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?
查看完整描述

3 回答

?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

您的方法存在的问题是您正在尝试解释bash脚本。首先,您只是尝试解释导出语句。然后您会发现人们正在使用变量扩展。以后人们将条件文件放入他们的文件中,或处理替代文件。最后,您将获得功能齐全的bash脚本解释器,其中包含大量错误。不要那样做


让Bash为您解释文件,然后收集结果。


您可以这样做:


#! /usr/bin/env python


import os

import pprint

import shlex

import subprocess


command = shlex.split("env -i bash -c 'source init_env && env'")

proc = subprocess.Popen(command, stdout = subprocess.PIPE)

for line in proc.stdout:

  (key, _, value) = line.partition("=")

  os.environ[key] = value

proc.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()。我认为是一个错误,但我离题了。


查看完整回答
反对 回复 2019-11-12
  • 3 回答
  • 0 关注
  • 383 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信