web-dev-qa-db-ja.com

Python-パイプでシェルコマンドを実行する方法?

Pythonで次のシェルコマンドを実行し、出力を取得したい場合があります。

echo This_is_a_testing | grep -c test

このpythonコードを使用して、Pythonで上記のシェルコマンドを実行できます。

>>> import subprocess
>>> subprocess.check_output("echo This_is_a_testing | grep -c test", Shell=True)
'1\n'

ただし、「Shell = True」オプションを使用したくないため、次のpythonコード、

>>> import subprocess
>>> p1 = subprocess.Popen(["echo", "This_is_a_testing"], stdout=subprocess.PIPE)
>>> p2 = subprocess.Popen(["grep", "-c", "test"], stdin=p1.stdout)
>>> p1.stdout.close()
>>> p2.communicate()
(None, None)

Webページの説明を参照したのに、なぜ出力が「なし」なのか疑問に思います。 http://docs.python.org/library/subprocess.html#subprocess.PIPE

私のコードのいくつかのポイントを見逃していましたか?提案/アイデアはありますか?前もって感謝します。

32
user1129812

マニュアルから:

結果タプルでNone以外のものを取得するには、stdout = PIPEおよび/またはstderr = PIPEを指定する必要があります

p2 = subprocess.Popen(["grep", "-c", "test"], stdin=p1.stdout, stdout=subprocess.PIPE)
26
Karoly Horvath
>>> import subprocess

>>> mycmd=subprocess.getoutput('df -h | grep home | gawk \'{ print $1 }\' | cut -d\'/\' -f3')

>>> mycmd 

'sda6'

>>>

受け入れられた答えは正解/動作中ですが、別のオプションはPopen.communicate()メソッドを使用してプロセスの標準入力に何かを渡すことです。

>>> import subprocess
>>> p2 = subprocess.Popen(["grep", "-c", "test"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
>>> p2.communicate("This_is_a_testing")
('1\n', None)
>>> print p2.returncode
0
>>>>

これにより、出力がpythonスクリプト自体で既にわかっている場合、出力をリダイレクトするためだけに別のコマンドを実行する必要がなくなります。

ただし、communicateには、プロセスが終了するまで待機するという副作用があります。非同期実行が必要な場合/ 2つのプロセスを使用することが望ましい場合があります。

5
dpr