少し変更された環境で外部コマンドを実行することは非常に一般的なケースだと思います。それが私がそれをする傾向がある方法です:
import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
私はもっと良い方法があると直感しています。大丈夫ですか?
少し変更された環境で外部コマンドを実行することは非常に一般的なケースだと思います。それが私がそれをする傾向がある方法です:
import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
私はもっと良い方法があると直感しています。大丈夫ですか?
os.environ.copy()
現在のプロセスのos.environを変更するつもりがない場合は、より良いと思います。
import subprocess, os
my_env = os.environ.copy()
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
それは問題が何であるかに依存します。環境のクローンを作成して変更する場合、1つの解決策は次のようになります。
subprocess.Popen(my_command, env=dict(os.environ, PATH="path"))
しかし、それは、置き換えられた変数が有効なpython識別子であるかどうかに多少依存します(英数字+アンダースコアではない環境変数名または数字で始まる変数に遭遇する頻度はどれくらいですか?)。
それ以外の場合は、次のように書くことができます。
subprocess.Popen(my_command, env=dict(os.environ,
**{"Not valid python name":"value"}))
非常に奇妙なケース(環境変数名で制御コードまたは非ASCII文字を使用する頻度はどれくらいですか?)では、環境のキーはbytes
(python3では)その構成を使用することさえできません。
ここで使用されている手法(特に最初の手法)は、通常、有効なPython識別子であり、事前に(コーディング時に)わかっているため、環境のキーにメリットがあります。2番目の手法には問題があります。そうでない場合は、おそらく別のアプローチを探す必要があります。
Python 3.5では、次のように実行できます。
import os
import subprocess
my_env = {**os.environ, 'PATH': '/usr/sbin:/sbin:' + os.environ['PATH']}
subprocess.Popen(my_command, env=my_env)
ここで、値のコピーos.environ
とオーバーライドが行われPATH
ます。
これは、 PEP 448(Additional Unpacking Generalizations)によって可能になりました。
もう一つの例。デフォルト環境(つまりos.environ
)があり、デフォルトをオーバーライドするdictがある場合は、次のように表現できます。
my_env = {**os.environ, **dict_with_env_variables}
元の環境で何らかの形で定義されていない場合my_env.get("PATH", '')
の代わりに使用することもできますが、それ以外は問題なく表示されます。my_env["PATH"]
PATH
os.envrionオブジェクトなどをコピーせずに環境変数を一時的に設定するには、次のようにします。
process = subprocess.Popen(['env', 'RSYNC_PASSWORD=foobar', 'rsync', \
'rsync://username@foobar.com::'], stdout=subprocess.PIPE)
envパラメーターは辞書を受け入れます。os.environを取得し、それにキー(必要に応じてdictのコピーに)を追加して、のパラメーターとして使用できますPopen
。
これはしばらくの間回答されていることは知っていますが、環境変数でPATHの代わりにPYTHONPATHを使用することについて知りたい点がいくつかあります。変更された環境を別の方法で処理するcronjobsを使用してPythonスクリプトを実行する方法の概要を説明しました(ここにあります)。私のように、この答えが提供するよりも少しだけ多くを必要としている人にとっては、それは良いことだと思いました。
特定の状況では、サブプロセスに必要な環境変数のみを渡したい場合がありますが、一般的には正しい考えを持っていると思います(私もそうしています)。