Python 2.5以前でシェルを使用せずに実行可能プロセスを作成する
-
05-07-2019 - |
質問
タイトルのとおり:
-
subprocess
モジュールは2.4および2.5で動作するはずなので使用できません - 引数を渡すためにシェルプロセスを生成しないでください。
(2)を説明するために、次のコードを検討してください:
>>> x=os.system('foo arg')
sh: foo: not found
>>> x=os.popen('foo arg')
sh: foo: not found
>>>
おわかりのように、 os.system
と os.popen
は、システムシェル(" sh")を介して指定されたコマンド(" foo")を実行します。これが発生するのは望ましくありません(そうしないと、見苦しい「見つかりません」というメッセージが制御なしでプログラムstderrに出力されます)。
最後に、このプログラム(上記の例では「arg」)に引数を渡すことができるはずです。
Python 2.5および2.4でこれを行うにはどうすればよいですか?
解決
おそらく、Python 2.4で利用可能なサブプロセスモジュールを使用する必要があります
Popen("/home/user/foo" + " arg")
>>> Popen("foo arg", shell=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/subprocess.py", line 595, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1092, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
シェルを使用していないため、フルパスを含める必要があります。
http://docs.python.org/library/subprocess .html#replacing-os-system
代わりに、subprocess.PIPEをstderrおよびstdoutに渡して、メッセージを抑制することもできます。詳細については、上記のリンクを参照してください。
他のヒント
前述のように、サブプロセスモジュールを使用できます(使用する必要があります)。
デフォルトでは、 shell
パラメーターは False
です。これは良いことであり、非常に安全です。また、完全なパスを渡す必要はなく、実行可能ファイル名と引数をシーケンス(タプルまたはリスト)として渡すだけです。
import subprocess
# This works fine
p = subprocess.Popen(["echo","2"])
# These will raise OSError exception:
p = subprocess.Popen("echo 2")
p = subprocess.Popen(["echo 2"])
p = subprocess.Popen(["echa", "2"])
サブプロセスモジュールで既に定義されている次の2つの便利な関数を使用することもできます。
# Their arguments are the same as the Popen constructor
retcode = subprocess.call(["echo", "2"])
subprocess.check_call(["echo", "2"])
stdout
や stderr
を PIPE
にリダイレクトできることを忘れないでください。したがって、画面には印刷されません(ただし、出力は、Pythonプログラムによる読み取りに引き続き使用可能です)。デフォルトでは、 stdout
と stderr
は両方とも None
です。これは、リダイレクトなしを意味し、同じものを使用しますPythonプログラムとしてstdout / stderr。
また、 shell = True
を使用して stdout
。 stderr
をPIPEにリダイレクトできるため、メッセージは出力されません。
# This will work fine, but no output will be printed
p = subprocess.Popen("echo 2", shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# This will NOT raise an exception, and the shell error message is redirected to PIPE
p = subprocess.Popen("echa 2", shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)