この質問に対する答えは、使用しているPythonのバージョンによって異なります。最も簡単な方法は、subprocess.check_output
関数を使用することです。
>>> subprocess.check_output(['ls', '-l'])
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
check_output
入力として引数のみを取る単一のプログラムを実行します。1に出力されたとおりに結果を返しますstdout
。に入力を書き込む必要がある場合stdin
はrun
、Popen
セクションまたはセクションに進んでください。複雑なシェルコマンドを実行する場合shell=True
は、この回答の最後にあるを参照してください。
このcheck_output
関数は、Pythonのほとんどすべてのバージョンで機能します(2.7以上)。2しかし、最近のバージョンでは、これは推奨されるアプローチではなくなりました。
最新バージョンのPython(3.5以降): run
Python 3.5以降を使用していて、下位互換性が必要ない場合は、新しいrun
関数をお勧めします。subprocess
モジュールに非常に一般的な高レベルAPIを提供します。プログラムの出力をキャプチャするには、subprocess.PIPE
フラグをstdout
キーワード引数に渡します。次にstdout
、返されたCompletedProcess
オブジェクトの属性にアクセスします。
>>> import subprocess
>>> result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE)
>>> result.stdout
b'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
戻り値はbytes
オブジェクトであるため、適切な文字列が必要な場合はdecode
それを行う必要があります。呼び出されたプロセスがUTF-8エンコードされた文字列を返すと仮定します。
>>> result.stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
これはすべてワンライナーに圧縮できます:
>>> subprocess.run(['ls', '-l'], stdout=subprocess.PIPE).stdout.decode('utf-8')
'total 0\n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 files\n'
プロセスのに入力を渡す場合は、キーワード引数にオブジェクトをstdin
渡します。bytes
input
>>> cmd = ['awk', 'length($0) > 5']
>>> input = 'foo\nfoofoo\n'.encode('utf-8')
>>> result = subprocess.run(cmd, stdout=subprocess.PIPE, input=input)
>>> result.stdout.decode('utf-8')
'foofoo\n'
stderr=subprocess.PIPE
(capture to result.stderr
)またはstderr=subprocess.STDOUT
(capture to result.stdout
と通常の出力)を渡すことでエラーをキャプチャできます。セキュリティが問題にならない場合はshell=True
、以下の注で説明するように渡すことで、より複雑なシェルコマンドを実行することもできます。
これにより、従来の方法と比較すると、少しだけ複雑になります。しかし、それは見返りの価値があると私は思います:これで、run
関数だけで行う必要があるほとんどすべてのことを実行できます。
古いバージョンのPython(2.7-3.4): check_output
古いバージョンのPythonを使用している場合、またはわずかな下位互換性が必要な場合は、check_output
上で簡単に説明した関数を使用できます。Python 2.7以降で利用可能です。
subprocess.check_output(*popenargs, **kwargs)
Popen
(以下を参照)と同じ引数を取り、プログラムの出力を含む文字列を返します。この回答の冒頭には、より詳細な使用例があります。Pythonの3.5およびそれ以上では、check_output
実行するのと同じですrun
とcheck=True
してstdout=PIPE
、とだけ返すstdout
属性を。
stderr=subprocess.STDOUT
エラーメッセージが返される出力に確実に含まれるように渡すことができますが、Pythonの一部のバージョンでは、に渡すとデッドロックが発生stderr=subprocess.PIPE
するcheck_output
可能性があります。セキュリティが問題にならない場合は、以下の注で説明するように渡すことで、より複雑なシェルコマンドを実行することもできます。shell=True
stderr
プロセスからパイプするか、プロセスに入力を渡す必要がある場合はcheck_output
、タスク次第ではありません。Popen
その場合は、以下の例を参照してください。
複雑なアプリケーションとPythonのレガシーバージョン(2.6以下): Popen
下位互換性が必要な場合、またはcheck_output
提供されているよりも高度な機能が必要な場合は、Popen
サブプロセスの低レベルAPIをカプセル化するオブジェクトを直接操作する必要があります。
Popen
コンストラクタは、いずれかの受け入れつのコマンド引数なし、またはリスト任意の数の引数リスト内の別個の項目として各続いて、その最初の項目としてコマンドを、含有します。shlex.split
文字列を適切にフォーマットされたリストに解析するのに役立ちます。Popen
オブジェクトは、プロセスIO管理および低レベル構成のためのさまざまな引数のホストも受け入れます。
入力を送信して出力をキャプチャすることcommunicate
は、ほとんどの場合、推奨される方法です。のように:
output = subprocess.Popen(["mycmd", "myarg"],
stdout=subprocess.PIPE).communicate()[0]
または
>>> import subprocess
>>> p = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE,
... stderr=subprocess.PIPE)
>>> out, err = p.communicate()
>>> print out
.
..
foo
を設定するとstdin=PIPE
、communicate
次を介してプロセスにデータを渡すこともできますstdin
。
>>> cmd = ['awk', 'length($0) > 5']
>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
... stderr=subprocess.PIPE,
... stdin=subprocess.PIPE)
>>> out, err = p.communicate('foo\nfoofoo\n')
>>> print out
foofoo
注アーロン・ホールの答え一部のシステムでは、あなたが設定する必要性があることを示し、stdout
、stderr
、およびstdin
すべてにPIPE
(またはDEVNULL
取得する)communicate
すべての仕事に。
まれに、複雑なリアルタイムの出力キャプチャが必要になる場合があります。Vartecの回答は前進する方法を示唆していますが、communicate
注意深く使用しないと、それ以外の方法ではデッドロックが発生しやすくなります。
上記のすべての関数と同様に、セキュリティが問題にならない場合は、を渡すことで、より複雑なシェルコマンドを実行できますshell=True
。
ノート
1.シェルコマンドの実行:shell=True
引数
通常、各呼び出しrun
、check_output
またはPopen
コンストラクタが実行される単一のプログラムを。つまり、派手なbashスタイルのパイプはありません。複雑なシェルコマンドを実行する場合はshell=True
、3つの関数すべてがサポートするを渡すことができます。
ただし、これを行うとセキュリティ上の問題が発生します。軽いスクリプト以外のことをしている場合は、各プロセスを個別に呼び出して、各プロセスの出力を入力として次のプロセスに渡すことをお勧めします。
run(cmd, [stdout=etc...], input=other_output)
または
Popen(cmd, [stdout=etc...]).communicate(other_output)
パイプを直接接続する誘惑は強いです。それに抵抗します。そうしないと、おそらくデッドロックが発生したり、このようなハックなことをしたりする必要があります。
2. Unicodeに関する考慮事項
check_output
Python 2では文字列が返されますが、bytes
Python 3ではオブジェクトが返されます。Unicodeについてまだ理解していない場合は、少し時間をかけて学ぶ価値があります。