web-dev-qa-db-ja.com

Python:os.systemの実行後にstdoutを取得する方法は?

os.system呼び出しを実行した後、変数にstdoutを取得したい。

この行を例としてみましょう。

batcmd="dir"
result = os.system(batcmd)

resultにはエラーコードが含まれます(Windowsではstderr0、上記の例では一部のLinuxでは1)。

実行されたコマンドでリダイレクトを使用せずに、上記のコマンドのstdoutを取得するにはどうすればよいですか?

71

必要なのがstdoutの出力だけである場合は、 subprocess.check_output() (Python 2.7で追加)を参照してください。

import subprocess

batcmd="dir"
result = subprocess.check_output(batcmd, Shell=True)

os.system()を使用していたため、Shell=Trueを設定して同じ動作を取得する必要があります。信頼できない引数をシェルに渡すことについて 大きな赤い警告メッセージ に注意してください。

stderrもキャプチャする必要がある場合は、呼び出しにstderr=subprocess.STDOUTを追加するだけです。

result = subprocess.check_output([batcmd], stderr=subprocess.STDOUT)

エラー出力をデフォルトの出力ストリームにリダイレクトします。

94
Martijn Pieters

これらの答えは私にはうまくいきませんでした。次のものを使用する必要がありました。

import subprocess
p = subprocess.Popen(["pwd"], stdout=subprocess.PIPE)
out = p.stdout.read()
print out

または関数として(Python 2.6.7ではShell = Trueを使用する必要があり、check_outputは2.7まで追加されなかったため、ここでは使用できません):

def system_call(command):
    p = subprocess.Popen([command], stdout=subprocess.PIPE, Shell=True)
    return p.stdout.read()
18
Patrick

Windowsソリューションを拡張したいと思います。 Python 2.7.5でIDLEを使用して、Expts.pyファイルからこのコードを実行すると:

import subprocess
r = subprocess.check_output('cmd.exe dir',Shell=False) 
print r

... Pythonシェルでは、「cmd.exe」に対応する出力のみを取得します。 「dir」部分は無視されます。しかし、/ Kや/ Cなどのスイッチを追加すると...

import subprocess
r = subprocess.check_output('cmd.exe /K dir',Shell=False) 
print r

...それからPythonシェルで、ディレクトリのリストを含むすべてのことを期待しています。わーい!

今、DOS Pythonコマンドウィンドウで、スイッチを使用せずに、または/ Kスイッチを使用して同じことを試みると、サブプロセスcmd.exeを実行しているためにウィンドウがハングするように見えます。それはさらに入力を待っています-「exit」と入力してから[enter]を押して解放します。ただし、/ Kスイッチを使用すると完全に機能し、pythonプロンプトに戻ります。じゃあね.

さらに一歩進んだ...これはクールだと思った...代わりにExpts.pyでこれを行うと:

import subprocess
r = subprocess.call("cmd.exe dir",Shell=False) 
print r

...新しいDOSウィンドウが開き、「dir」ではなく「cmd.exe」の結果のみが表示されます。/Cスイッチを追加すると、DOSウィンドウが非常に速く開いたり閉じたりしてから、何かを見ることができます(予想どおり、/ Cは終了すると終了します)。代わりに/ Kスイッチを追加すると、DOSウィンドウが開いたままになり、ディレクトリリストを含むすべての出力が表示されます。

DOS Pythonコマンドウィンドウから同じこと(subprocess.check_outputではなくsubprocess.call)を試してみると、すべての出力は同じウィンドウ内にあり、ポップアップウィンドウはありません。スイッチを使用しない場合、「dir」部分は無視され、プロンプトはpythonプロンプトからDOSプロンプトに変わります(cmd.exeサブプロセスがpythonで実行されているため、再び「exit」と入力し、 pythonプロンプトに戻ります)。/Kスイッチを追加すると、ディレクトリリストが出力され、/ Kがサブプロセスを終了しないため、プロンプトがpythonからDOSに変更されます。スイッチを/ Cに変更すると、期待されるすべての出力が得られ、サブプロセスは/ Cに従って終了するため、pythonプロンプトに戻ります。

長時間の回答で申し訳ありませんが、このボードでは多くの簡潔な「回答」でイライラしています(せいぜいテストされていないためです-私の上のEduard Fの回答はスイッチがありません)またはさらに悪いことに、あまり役に立たないほど簡潔です(たとえば、「os.systemの代わりにサブプロセスを試してください」...ええ、OK、今何??)。対照的に、私はテストしたソリューションを提供し、それらの間に微妙な違いがあることを示しました。多くの時間を費やしましたが...これが役立つことを願っています.

5
LateNiteOwl

commandsも機能します。

import commands
batcmd = "dir"
result = commands.getoutput(batcmd)
print result

Linux、python 2.7で動作します。

3
buxizhizhoum

サブプロセスが大きなタスクのためにメモリエラーを与えていたため、os.systemを使用する必要がありました。この問題のリファレンス here 。したがって、os.systemコマンドの出力を取得するために、この回避策を使用しました。

import os

batcmd = 'dir'
result_code = os.system(batcmd + ' > output.txt')
if os.path.exists('output.txt'):
    fp = open('output.txt', "r")
    output = fp.read()
    fp.close()
    os.remove('output.txt')
    print(output)
1
Edhowler