Python,在使用Popen时更改当前的shell环境变量?

时间:2011-11-12 00:53:43

标签: python

我有一个XML,其中包含有关通过我的python脚本设置到shell中的环境变量的信息。以下是XML的摘录:

<envVar name='QTDIR'>/homeqt/libs.qt4/qt4.5.1</envVar>
<envVar name='MAKE'>which make</envVar>

这部分片段告诉我的python脚本设置环境变量QTDIR和MAKE。

我担心的是如何设置上述变量。我知道我可以使用os.environ设置环境变量并执行以下操作:

os.environ['QTDIR'] = "/homeqt/libs.qt4/qt4.5.1"

但我无法使用它来设置我的MAKE变量,我必须执行命令“ make ”(以获取make可执行文件的路径)。我的目标是使用相同的方法/函数来设置每个变量。

所以,我想做这样的事情:

Popen("QTDIR=/homeqt/libs.qt4/qt4.5.1 ; export QTDIR", shell=True, stdout=PIPE, stderr=PIPE)
Popen("MAKE=which make ; export MAKE", shell=True, stdout=PIPE, stderr=PIPE)

但如果我这样做,变量将仅为子进程设置,而不是为当前shell设置。

所以,我的问题是,有没有办法做我想要的?我不想分析XML并做这样的事情:

(伪代码)

if QTDIR has normal value
    os.environ['QTDIR'] = "/homeqt/libs.qt4/qt4.5.1"
if MAKE has value to be executed
    p = Popen("which make", shell=True, stdout=PIPE, stderr=PIPE)
    stdout, stderr = p.communicate()
    os.environ['MAKE'] = stdout

2 个答案:

答案 0 :(得分:3)

我会使用XML属性。

<envVar name="MAKE" type="command">which make</envVar>
<envVar name="QTDIR" type="string">/homeqt/libs.qt4/qt4.5.1</envVar>

伪代码取决于您的xml库:

if node.attributes['type'] == 'command':
    value = os.popen(node.firstChild.text).read()
elif node.attributes['type'] == 'string':
    value = node.firstChild.text
os.environ[node.attributes['name']] = value

答案 1 :(得分:0)

您的陈述含糊不清:

<envVar name='QTDIR'>/homeqt/libs.qt4/qt4.5.1</envVar>
<envVar name='MAKE'>which make</envVar>

您如何决定MAKE=which makeMAKE=`which make`

$ a=which make ; echo $a
make: *** No targets specified and no makefile found.  Stop.

$ a=`which make` ; echo $a
/usr/bin/make

$ a='which make' ; echo $a
which make

如果xml文件是机器生成的,并且人们不经常查看/编辑此文件,那么您可以使用详细的显式表示法,例如suggested by @stefan

否则可能会使用更简洁和简单的表示形式:

QTDIR: /homeqt/libs.qt4/qt4.5.1
$MAKE: which make

这是一个将该格式解析为字典的Python脚本:

for line in file:
    name, sep, value = map(str.strip, line.partition(':'))
    if sep: # ':' is in the line           
       if name.startswith('$'):
          name = name[1:] # strip '$'
          value = subprocess.check_output(value, shell=True).strip()
       d[name] = value

或者你可以这样做:

d = yaml.load(file) # yaml is as complex as xml, but less explicit i.e., worse
# and transform keys that start with '$' here
如果你需要更复杂的功能,那么xml格式可能是合理的后备。