Получение выходных данных подпроцесса.звоните() [дубликат]
этот вопрос уже есть ответ здесь:
как я могу получить результат запуска процесса с помощью 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'
>>>
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.
на
Ipythonshell: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