8

Python 実行プロセスの環境を変更しようとしています。それを行う正しい方法は、os.environ と対話することであるようです。ただし、次のアサーションは失敗します。

import os, subprocess
os.environ['ATESTVARIABLE'] = 'value'
value = subprocess.check_output(['echo', '$ATESTVARIABLE'], shell=True)
assert 'value' in value

現在の環境を変えるために他にすべきことはありますか?上記のコードによって明らかになった私の Python の理解の欠陥は何ですか :)?

(現在の Python インタープリター内には、期待される値が含まれていることに注意してください。特定の環境変数を必要とし、外部プロセスを起動する可能性のあるコードを実行するように設定しています。明らかに、特定のサブプロセスos.environ['ATESTVARIABLE']の環境を制御したい場合は、 env キーワードを使用します。)

4

2 に答える 2

5

モジュールのソースコードを見るとsubprocess、引数のリストを使用するshell=Trueと...と同等のことが行われるためです。

/bin/sh -c 'echo' '$ATESTVARIABLE'

...欲しいものが...

/bin/sh -c 'echo $ATESTVARIABLE'

以下は私のために働く...

import os, subprocess

os.environ['ATESTVARIABLE'] = 'value'
value = subprocess.check_output('echo $ATESTVARIABLE', shell=True)
assert 'value' in value

アップデート

FWIW、2つの違いは、最初のフォーム...

/bin/sh -c 'echo' '$ATESTVARIABLE'

echo...パラメータなしでシェルの組み込みを呼び出すだけで$0、リテラル文字列'$ATESTVARIABLE'に設定されます。たとえば...

$ /bin/sh -c 'echo $0'
/bin/sh
$ /bin/sh -c 'echo $0' '$ATESTVARIABLE'
$ATESTVARIABLE

...一方、2 番目のフォームは...

/bin/sh -c 'echo $ATESTVARIABLE'

echo...環境変数の値に等しい単一のパラメーターでシェルの組み込みを呼び出しますATESTVARIABLE

于 2013-06-25T20:22:42.973 に答える
4

実際、次のコードの何が問題なのですか。

import os, subprocess
os.environ['ATESTVARIABLE'] = 'value'
value = subprocess.check_output(['echo', '$ATESTVARIABLE'], shell=True)
assert 'value' in value

subprocessのヘルプページをよく読んでいないということです:

shell=True の Unix では、シェルはデフォルトで /bin/sh になります。args が文字列の場合、その文字列はシェルを介して実行するコマンドを指定します。つまり、シェル プロンプトで入力したときとまったく同じように文字列をフォーマットする必要があります。これには、たとえば、スペースを含むファイル名を引用またはバックスラッシュでエスケープすることが含まれます。args がシーケンスの場合、最初の項目はコマンド文字列を指定し、追加の項目はシェル自体への追加の引数として扱われます。つまり、Popen は以下と同等のことを行います。

Popen(['/bin/sh', '-c', args[0], args[1], ...])

これはsubprocess.check_out()、配列を最初のパラメーターとして呼び出すと、期待した結果が得られないことを意味します。次のコードで再試行する必要があります。

import os, subprocess
os.environ['ATESTVARIABLE'] = 'value'
value = subprocess.check_output('echo $ATESTVARIABLE', shell=True)
assert 'value' in value

期待どおりに動作するはずです。

それ以外の場合は、環境変数に関するあなたの理解は正しいです。環境を変更すると、現在のプロセスのフォークされたすべての子にその環境が与えられます。

于 2013-06-25T21:23:53.500 に答える