Subprocess.check_output()に関するドキュメントを見つけましたが、引数のあるドキュメントを見つけることができず、ドキュメントの深さがあまりありません。 Python 3を使用しています(ただし、Python 3を介してPython 2ファイルを実行しようとしています)
このコマンドを実行しようとしています:python py2.py -i test.txt
-iはargparseの位置引数、test.txtは-i、py2.pyは実行するファイルです
私は以下を含む多くの(動作しない)バリエーションを試しました:py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])
py2output = subprocess.check_output([str('python'),'py2.py','-i', test.txt'])
正解(Python 2.7以降を使用、check_output()
当時導入されていた ):
py2output = subprocess.check_output(['python','py2.py','-i', 'test.txt'])
実証するために、ここに私の2つのプログラムを示します。
py2.py:
import sys
print sys.argv
py3.py:
import subprocess
py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'])
print('py2 said:', py2output)
実行する:
$ python3 py3.py
py2 said: b"['py2.py', '-i', 'test.txt']\n"
各バージョンの問題点は次のとおりです。
py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])
まず、str('python py2.py')
は'python py2.py'
とまったく同じです。str
を取得し、str
を呼び出してstr
に変換します。これにより、コードは読みにくくなり、長くなり、さらに遅くなりますが、利点はありません。
さらに深刻なのは、python py2.py
という名前のプログラムを実際に実行しようとしていない限り、/usr/bin/python\ py2.py
を単一の引数にすることはできません。あなたはそうではありません。たとえば、/usr/bin/python
を最初の引数py2.py
で実行しようとしています。そのため、リスト内の要素を個別に作成する必要があります。
2番目のバージョンで修正されますが、'
の前にtest.txt'
がありません。これにより、おそらくEOL while scanning string literal
と言うSyntaxError
が表示されます。
その間、どのようにしてドキュメントを見つけたのかはわかりませんが、引数のある例は見つかりませんでした。最初の例は次のとおりです。
>>> subprocess.check_output(["echo", "Hello World!"])
b'Hello World!\n'
追加の引数"echo"
を指定して"Hello World!"
コマンドを呼び出します。
また:
-iはargparseの位置引数であり、test.txtは-iです
-i
はnotではなく、オプションの引数であると確信しています。そうでなければ、文の後半は意味をなしません。
@abarnertが言及したものに追加する
より良い方法は、例外をキャッチすることです
import subprocess
try:
py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'],stderr= subprocess.STDOUT)
#print('py2 said:', py2output)
print "here"
except subprocess.CalledProcessError as e:
print "Calledprocerr"
このstderr = subprocess.STDOUTは、stderrでfilenotfoundエラーを取得しないようにするためのものです。通常、filenotfoundexceptionでキャッチすることはできません。
python: can't open file 'py2.py': [Errno 2] No such file or directory
事実、これに対するより良い解決策は、ファイル/スクリプトが存在するかどうかを確認してから、ファイル/スクリプトを実行することです
Python 3.5以降、- subprocess.check_output() よりも subprocess.run() が推奨されます。
>>> subprocess.run(['cat','/tmp/text.txt'], stdout=subprocess.PIPE).stdout
b'First line\nSecond line\n'
上記の代わりにPython 3.7以降、capture_output=true
パラメーターを使用してstdoutとstderrをキャプチャできます。
>>> subprocess.run(['cat','/tmp/text.txt'], capture_output=True).stdout
b'First line\nSecond line\n'
また、バイナリの代わりにPython 3.7 universal_newlines=True
以降のテキストを操作するために、text=True
またはその同等物を使用することもできます。
>>> stdout = subprocess.run(['cat', '/tmp/text.txt'], capture_output=True, text=True).stdout
>>> print(stdout)
First line
Second line
詳細については、 subprocess.run() documentationを参照してください。