web-dev-qa-db-ja.com

環境変数をpythonスクリプトで設定

環境変数を設定してコマンドを実行するbashスクリプトがあります

LD_LIBRARY_PATH=my_path
sqsub -np $1 /homedir/anotherdir/executable

コマンドに渡す引数の一部を計算するため、bashの代わりにpythonを使用します。

私が試してみました

putenv("LD_LIBRARY_PATH", "my_path")

そして

call("export LD_LIBRARY_PATH=my_path")

に続く

call("sqsub -np " + var1 + "/homedir/anotherdir/executable")

しかし、LD_LIBRARY_PATHが設定されていないため、プログラムは常にあきらめます。

どうすれば修正できますか?

手伝ってくれてありがとう!

(pythonスクリプトがすべて機能する前にLD_LIBRARY_PATHをエクスポートする場合、パスを決定し、環境変数を正しい値に設定するにはpython

48
Matthias 009

バッシュ:

LD_LIBRARY_PATH=my_path
sqsub -np $1 /path/to/executable

Pythonでも同様:

import os
import subprocess
import sys

os.environ['LD_LIBRARY_PATH'] = "my_path" # visible in this process + all children
subprocess.check_call(['sqsub', '-np', sys.argv[1], '/path/to/executable'],
                      env=dict(os.environ, SQSUB_VAR="visible in this subprocess"))
54
jfs

以下を使用して、環境に要素を追加できます。

os.environ['LD_LIBRARY_PATH'] = 'my_path'

を使用して、シェル(os.environを使用する)でサブプロセスを実行します

subprocess.call('sqsub -np ' + var1 + '/homedir/anotherdir/executable', Shell=True)
11
Manbeardo

ここには多くの良い答えがありますが、Shell=True_を使用して信頼できない変数をサブプロセスに渡すことは絶対に避けてくださいこれはセキュリティリスクです。変数はシェルにエスケープし、任意のコマンドを実行できます!避けられない場合は、少なくともpython3のshlex.quote()を使用して文字列をエスケープします(スペースで区切られた引数が複数ある場合は、文字列全体ではなく各分割を引用してください)。

_Shell=False_は、常に引数配列を渡すデフォルトです。

今、safeソリューション...

方法#1

独自のプロセスの環境を変更する-新しい環境はpython自体とすべてのサブプロセスに適用されます。

_os.environ['LD_LIBRARY_PATH'] = 'my_path'
command = ['sqsub', '-np', var1, '/homedir/anotherdir/executable']
subprocess.check_call(command)
_

方法#2

環境のコピーを作成し、子供に渡します。あなたは子供の環境を完全に制御しており、Python自身の環境には影響しません。

_myenv = os.environ.copy()
myenv['LD_LIBRARY_PATH'] = 'my_path'
command = ['sqsub', '-np', var1, '/homedir/anotherdir/executable']
subprocess.check_call(command, env=myenv)
_

方法#3

Unixのみ:envを実行して環境変数を設定します。 portabeではなく、変更する変数が多い場合はさらに面倒ですが、#2のようにpythonおよびchildren環境を完全に制御できます。

_command = ['env', 'LD_LIBRARY_PATH=my_path', 'sqsub', '-np', var1, '/homedir/anotherdir/executable']
subprocess.check_call(command)
_

もちろん、_var1_にスペースで区切られた複数の引数が含まれている場合、それらはスペースを含む単一の引数として渡されます。 _Shell=True_で元の動作を維持するには、分割された文字列を含むコマンド配列を作成する必要があります。

_command = ['sqsub', '-np'] + var1.split() + ['/homedir/anotherdir/executable']
_