310

を使用して実行されたプロセスの出力を取得するにはどうすればよいsubprocess.call()ですか?

StringIO.StringIOにオブジェクトを渡すとstdout、次のエラーが発生します。

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 444, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 588, in __init__
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/subprocess.py", line 945, in _get_handles
    c2pwrite = stdout.fileno()
AttributeError: StringIO instance has no attribute 'fileno'
>>> 
4

7 に答える 7

308

Pythonのバージョンが2.7以上の場合は、subprocess.check_outputを使用できます。これは、基本的に必要な処理を正確に実行します(標準出力を文字列として返します)。

簡単な例(Linuxバージョン、注を参照):

import subprocess

print subprocess.check_output(["ping", "-c", "1", "8.8.8.8"])

pingコマンドは(-cカウントに)Linux表記を使用していることに注意してください。-nWindowsでこれを試す場合は、同じ結果になるように変更することを忘れないでください。

以下にコメントされているように、この他の回答でより詳細な説明を見つけることができます。

于 2012-01-02T11:45:57.813 に答える
224

からの出力はsubprocess.call()、ファイルにのみリダイレクトする必要があります。

subprocess.Popen()代わりに使用する必要があります。次にsubprocess.PIPE、stderr、stdout、および/またはstdinパラメーターを渡し、次のcommunicate()方法を使用してパイプから読み取ることができます。

from subprocess import Popen, PIPE

p = Popen(['program', 'arg1'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
output, err = p.communicate(b"input data that is passed to subprocess' stdin")
rc = p.returncode

理由は、によって使用されるファイルのようなオブジェクトsubprocess.call()には実際のファイル記述子が必要であり、したがってfileno()メソッドを実装する必要があるためです。ファイルのようなオブジェクトを使用するだけではうまくいきません。

詳細については、こちらをご覧ください。

于 2010-01-03T22:13:40.523 に答える
85

Python 3.5以降では、サブプロセスモジュールのrun関数を使用することをお勧めします。これによりCompletedProcessオブジェクトが返され、そこから出力と戻りコードを簡単に取得できます。

from subprocess import PIPE, run

command = ['echo', 'hello']
result = run(command, stdout=PIPE, stderr=PIPE, universal_newlines=True)
print(result.returncode, result.stdout, result.stderr)
于 2016-01-19T09:44:30.413 に答える
51

私は次の解決策を持っています。実行された外部コマンドの終了コード、stdout、およびstderrもキャプチャします。

import shlex
from subprocess import Popen, PIPE

def get_exitcode_stdout_stderr(cmd):
    """
    Execute the external command and get its exitcode, stdout and stderr.
    """
    args = shlex.split(cmd)

    proc = Popen(args, stdout=PIPE, stderr=PIPE)
    out, err = proc.communicate()
    exitcode = proc.returncode
    #
    return exitcode, out, err

cmd = "..."  # arbitrary external command, e.g. "python mytest.py"
exitcode, out, err = get_exitcode_stdout_stderr(cmd)

こちらにもブログ投稿があります

編集:ソリューションは、tempに書き込む必要のない新しいソリューションに更新されました。ファイル。

于 2014-01-08T15:50:06.080 に答える
31

私は最近、これを行う方法を理解しました。これが私の現在のプロジェクトからのサンプルコードです。

#Getting the random picture.
#First find all pictures:
import shlex, subprocess
cmd = 'find ../Pictures/ -regex ".*\(JPG\|NEF\|jpg\)" '
#cmd = raw_input("shell:")
args = shlex.split(cmd)
output,error = subprocess.Popen(args,stdout = subprocess.PIPE, stderr= subprocess.PIPE).communicate()
#Another way to get output
#output = subprocess.Popen(args,stdout = subprocess.PIPE).stdout
ber = raw_input("search complete, display results?")
print output
#... and on to the selection process ...

これで、コマンドの出力が変数「output」に保存されました。「stdout=subprocess.PIPE」は、Popen内から「stdout」という名前のファイルオブジェクトを作成するようにクラスに指示します。私の知る限り、communicate()メソッドは、実行したプロセスからの出力とエラーのタプルを返すための便利な方法として機能します。また、Popenをインスタンス化するときにプロセスが実行されます。

于 2010-07-14T14:42:34.923 に答える
24

重要なのは機能を使うことですsubprocess.check_output

たとえば、次の関数は、プロセスのstdoutとstderrをキャプチャし、それと、呼び出しが成功したかどうかを返します。Python2および3と互換性があります。

from subprocess import check_output, CalledProcessError, STDOUT

def system_call(command):
    """ 
    params:
        command: list of strings, ex. `["ls", "-l"]`
    returns: output, success
    """
    try:
        output = check_output(command, stderr=STDOUT).decode()
        success = True 
    except CalledProcessError as e:
        output = e.output.decode()
        success = False
    return output, success

output, success = system_call(["ls", "-l"])

コマンドを配列ではなく文字列として渡したい場合は、次のバージョンを使用してください。

from subprocess import check_output, CalledProcessError, STDOUT
import shlex

def system_call(command):
    """ 
    params:
        command: string, ex. `"ls -l"`
    returns: output, success
    """
    command = shlex.split(command)
    try:
        output = check_output(command, stderr=STDOUT).decode()
        success = True 
    except CalledProcessError as e:
        output = e.output.decode()
        success = False
    return output, success

output, success = system_call("ls -l")
于 2017-11-06T20:08:42.523 に答える
16

シェルIpython内:

In [8]: import subprocess
In [9]: s=subprocess.check_output(["echo", "Hello World!"])
In [10]: s
Out[10]: 'Hello World!\n'

sargueの答えに基づいています。sargueの功績。

于 2015-09-05T13:14:48.190 に答える