Получение выходных данных подпроцесса.звоните() [дубликат]



этот вопрос уже есть ответ здесь:



как я могу получить результат запуска процесса с помощью 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'
>>>
480   7  

7 ответов:

вывод 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() метод. Просто с помощью любого файла, как объект не будет делать трюк.

посмотреть здесь для получения дополнительной информации.

Если у вас есть версия Python >= 2.7, вы можете использовать подпроцесс.check_output который в основном делает именно то, что вы хотите (она возвращает стандартный вывод в виде строки).

простой пример (версия linux, см. Примечание):

import subprocess

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

обратите внимание, что команда ping использует нотацию linux (-c для графа). Если вы попробуете это в Windows, не забудьте изменить его на -n для того же результата.

как прокомментировал ниже вы можете найти более подробное объяснение в этот и другие ответы.

У меня есть следующее решение. Он захватывает код выхода, 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)

У меня также есть сообщение в блоге на нем здесь.

Edit: решение было обновлено до более нового, которому не нужно писать в temp. файлы.

для Python 3.5+ рекомендуется использовать запустить функцию из модуля подпроцесс. Это возвращает 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)

недавно я просто понял, как это сделать, и вот пример кода из моего текущего проекта:

#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 = подпроцесса.PIPE "сообщает классу создать файловый объект с именем 'stdout' из Popen. Метод communicate (), из того, что я могу сказать, просто действует как удобный способ вернуть кортеж вывода и ошибок из процесса, который вы запустили. Кроме того, процесс является запуск при создании экземпляра Popen.

на Ipython shell:

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

на основе ответа сарга. Надо отдать должное саргу.

следующее захватывает stdout и stderr процесса в одной переменной. Это Python 2 и 3 совместимы:

from subprocess import check_output

command = ["ls", "-l"]
try:
    output = check_output(command, stderr=STDOUT).decode()
    success = True 
except CalledProcessError as e:
    output = e.output.decode()
    success = False

Если ваша команда является строкой, а не массивом, префикс этого:

import shlex
command = shlex.split(command)

Comments

    Ничего не найдено.