Как скрыть вывод подпроцесса в Python 2.7
Я использую eSpeak на Ubuntu и имею Python 2.7 script, который печатает и говорит сообщение:
import subprocess
text = 'Hello World.'
print text
subprocess.call(['espeak', text])
eSpeak производит нужные звуки, но загромождает оболочку с некоторыми ошибками (ALSA lib..., no socket connect), поэтому я не могу легко прочитать то, что было напечатано ранее. Код выхода равен 0.
К сожалению, нет документального варианта, чтобы отключить его многословие, поэтому я ищу способ только визуально отключить его и сохранить открытую оболочку чистой для дальнейшего взаимодействия.
Как я могу это сделать?
Ответы
Ответ 1
Перенаправить вывод в DEVNULL:
import os
import subprocess
FNULL = open(os.devnull, 'w')
retcode = subprocess.call(['echo', 'foo'], stdout=FNULL, stderr=subprocess.STDOUT)
Это фактически то же самое, что и выполнение этой команды оболочки:
retcode = os.system("echo 'foo' &> /dev/null")
Ответ 2
Здесь более портативная версия (просто для удовольствия, в вашем случае это не обязательно):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from subprocess import Popen, PIPE, STDOUT
try:
from subprocess import DEVNULL # py3k
except ImportError:
import os
DEVNULL = open(os.devnull, 'wb')
text = u"René Descartes"
p = Popen(['espeak', '-b', '1'], stdin=PIPE, stdout=DEVNULL, stderr=STDOUT)
p.communicate(text.encode('utf-8'))
assert p.returncode == 0 # use appropriate for your program error handling here
Ответ 3
Используйте subprocess.check_output
(новый в python 2.7). Он отключит stdout и вызовет исключение, если команда завершится с ошибкой. (Он фактически возвращает содержимое stdout, поэтому вы можете использовать его позже в своей программе, если хотите.) Пример:
import subprocess
try:
subprocess.check_output(['espeak', text])
except subprocess.CalledProcessError:
# Do something
Вы также можете подавить stderr с помощью:
subprocess.check_output(["espeak", text], stderr=subprocess.STDOUT)
Для более ранних, чем 2.7, используйте
import os
import subprocess
with open(os.devnull, 'w') as FNULL:
try:
subprocess._check_call(['espeak', text], stdout=FNULL)
except subprocess.CalledProcessError:
# Do something
Здесь вы можете подавить stderr с помощью
subprocess._check_call(['espeak', text], stdout=FNULL, stderr=FNULL)
Ответ 4
Начиная с Python3 вам больше не нужно открывать devnull и вы можете вызвать subprocess.DEVNULL.
Ваш код будет обновлен как таковой:
import subprocess
text = 'Hello World.'
print(text)
subprocess.call(['espeak', text], stderr=subprocess.DEVNULL)
Ответ 5
если вы используете модуль подпроцесса в окнах (не конкретно для этого вопроса, но соответствует заголовку) с python 2.7x, и это ТОЛЬКО ошибки, которые вы хотите подавить (специфичные для этого вопроса), вы можете сделать что-то вроде это:
output = subprocess.check_output(["arp", "-a", "-N", "127.0.0.2"], stderr=subprocess.STDOUT)
вы должны быть в состоянии проверить, используя код выше в вашей системе, но если 127.0.0.2 существует в вашей таблице arp, вы можете просто выбрать ip, у которого нет никола, связанного с ним.
Ответ 6
Почему бы не использовать command.getoutput() вместо?
import commands
text = "Mario Balotelli"
output = 'espeak "%s"' % text
print text
a = commands.getoutput(output)