2011-11-12 66 views
1

我有一个XML,它包含有关由我的python脚本设置到shell中的环境变量的信息。这里是XML的片段:Python,使用Popen时更改当前shell环境变量?

<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可执行文件的路径)。我的目标是使用相同的方法/函数来设置每个变量。

所以,我认为做这样的事情:

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 
+1

你为什么不想要? – Amber

+0

我们有非常复杂的bash shell脚本,如果其他人构建我们的产品,则需要大量的shell脚本。我想在XML中尽可能移动大量信息,并使python脚本调用从中提取的作业。我希望python脚本尽可能简单。这就是为什么。那么,有可能吗? – peterphonic

+0

@peterphonic所以,你想有一些值得特别处理,但你不愿意在任何地方处理它们? – millimoose

回答

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

好的答案!更好的是,升级到Nick Coghlan一直倡导的'subprocess.check_output()'标准库方法,因为它有更好的设计。 –

+0

我只是搞砸了,我同意这是一个更好的解决方案,但可能不是这个。这就需要你对自己解析命令,如check_output发生在一个参数数组,所以你可能要尝试像check_output(command.split(”“)),这仅仅是个坏消息,不会做正确的几乎所有情况下都是这样(如果我引用了字符串,转义空格或分号,那么在它们旁边没有空格的情况下呢?)最好将它传递给shell的语法分析器。 – stefan

+0

只需将'shell = True'传递给函数:'check_output(command,shell = True)' –

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格式可能是合理的回退。

+0

其实区别,我认为XML是一个更好的解决方案。它不仅包含有关变量的信息,也有执行的作业:。\t \t \t <作业标签='Create_Directories '> \t \t \t \t cd $ MAINPATH; \t \t \t \t mkdir -p $ TARGET; \t \t \t \t cd“$ MAINPATH/$ TARGET”; \t \t \t \t室射频$ VARIANT \t \t \t – peterphonic

+0

@peterphonic:在这种情况下,DB,如源码可能更适合于跟踪工作状态。 – jfs