Python、Popenを使用している間、現在のシェル環境変数を変更しますか?

私はPythonスクリプトでシェルに設定する環境変数に関する情報を含むXMLを持っています。 XMLの抜粋です:

/homeqt/libs.qt4/qt4.5.1
which make

このスニペットのこの部分は、私の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)

しかし、これを行うと、変数は現在のシェルではなくサブプロセスに対してのみ設定されます。

だから、私の質問は、私がしたいことをする方法があるということですか?私は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
私たちは非常に複雑なbashシェルスクリプトを用意しています。私はできるだけ多くの情報をXML内で移動し、Pythonスクリプトがそれから抽出されたジョブを呼び出すようにしたい。私はpythonスクリプトをできるだけシンプルにしたい。それが理由です。それで、それは可能ですか?
追加された 著者 peterphonic,
ええ、このようなものは何か=)私は以下の解決策がより理にかなっていると思います...
追加された 著者 peterphonic,
なぜあなたはしたくないのですか?
追加された 著者 Amber,
@peterphonicだから、あなたは特別に扱わなければならないいくつかの値を持ちたいと思っていますが、あなたは特別にどこでもそれらを扱うつもりはありませんか?
追加された 著者 millimoose,

2 答え

XML属性を使用します。

which make
/homeqt/libs.qt4/qt4.5.1

あなたの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
3
追加された
@stefan: os.popen()。read()は、エラーと空の出力を区別しません。
追加された 著者 jfs,
いい答えです!さらに優れた設計のため、Nick Coghlanが主張してきた subprocess.check_output()標準ライブラリメソッドにアップグレードしてください。
追加された 著者 Brandon Rhodes,
check_output(command、shell = True)に関数に shell = True
追加された 著者 Brandon Rhodes,
実際、Nickが標準ライブラリのドキュメントで行ってきた素晴らしい作業と一致するようにドキュメントストリングを更新できるようにバグを提出することを検討します。ここでは check_output()また、 shell のような引数を取ることを明確にしました: docs.python .org/library/subprocess.html
追加された 著者 Brandon Rhodes,
私はちょうどこれを混乱させました、そして、私はこれがいくつかの状況のた​​めのよりよい解決であることに同意します、しかし、おそらくこれはそうではありません。 check_outputは引数の配列をとるので、check_output(command.split( ''))のようなものを試す必要があります。これは悪いニュースであり、正しいことをしませんほぼすべての場合(シェルの隣に空白を入れずに文字列、エスケープスペース、セミコロンを引用するとどうなりますか?)シェルの文法パーサに渡す方が良いでしょう。
追加された 著者 stefan,
ああこの引数はヘルプページには書かれていません:(
追加された 著者 stefan,

あなたの表現はあいまいです。

/homeqt/libs.qt4/qt4.5.1
which make

どのようにして MAKE = which makeMAKE = `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ファイルがマシンで生成され、人間がこのファイルを頻繁に表示/編集しない場合は、 @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がより良い解決策だと思います。変数に関する情報だけでなく、実行する必要のあるジョブも含まれています。 cd $ MAINPATH; mkdir -p $ TARGET; cd "$ MAINPATH/$ TARGET"; rm -rf $ VARIANT
追加された 著者 peterphonic,
@peterphonic:この場合、sqliteなどのdbはジョブの状態を追跡するのに適しています。
追加された 著者 jfs,