2011-11-12 9 views
1

私はPythonスクリプトでシェルに設定する環境変数に関する情報を含むXMLを持っています。Popenを使用しているときにPython、現在のシェル環境変数を変更しますか?

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

このスニペットのこの部分は、環境変数QTDIRを設定して作るために私のPythonスクリプトに指示します:ここではXMLの抜粋です。

私の懸念は、上記の変数を設定する方法の違いです。

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

しかし、私は私のMAKE変数を設定し、これを使用することはできません、私はコマンドを実行する必要がある」 を作るた:私は、環境変数を設定して、このような何かをするためにはos.environ使用できることを知っています"(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) 

をしかし、私はこれを行う場合、変数がない現在のシェルのために、サブプロセスにのみ設定されます。

私の質問は、私が欲しいものをする方法があるということですか?私は、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シェルスクリプトを用意しています。私はできるだけ多くの情報を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( ''))のようなものを試す必要があります。これは悪いニュースであり、正しいことをしませんほぼすべての場合(シェルの隣に空白を入れずに文字列、エスケープスペース、セミコロンを引用するとどうなりますか?)シェルの文法パーサに渡す方が良いでしょう。 – 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 makeまたはMAKE=`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 \t \t \t \t cd $ MAINPATH; \t \t \t \t mkdir -p $ TARGET; \t \t \t \t cd "$ MAINPATH/$ TARGET"; \t \t \t \tのrm -rf $ VARIANT \t \t \t peterphonic

+0

@peterphonic:このケースでは、このようなsqliteのようデシベルは、ジョブの状態を追跡する方が適切でした。 – jfs

関連する問題