Подавить вывод в вызовах Python исполняемых файлов
У меня есть бинарный файл A
который генерирует вывод при вызове. Если я вызываю его из оболочки Bash, большая часть вывода подавляется A > /dev/null
, Весь вывод подавляется A &> /dev/null
У меня есть скрипт на Python с именем B
что нужно позвонить A
, Я хочу иметь возможность генерировать вывод из B
подавляя все выходные данные A
,
Изнутри B
, Я пробовал os.system('A')
, os.system('A > /dev/null')
, а также os.system('A &> /dev/null')
, os.execvp('...')
и т. д., но ни один из них не подавляет весь вывод A.
Я мог бежать B &> /dev/null
, но это подавляет все B
выход тоже, и я не хочу этого.
У кого-нибудь есть предложения?
9 ответов
Если у вас есть Python 2.4, вы можете использовать модуль подпроцесса:
>>> import subprocess
>>> s = subprocess.Popen(['cowsay', 'hello'], \
stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0]
>>> print s
_______
< hello >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
import os
import subprocess
command = ["executable", "argument_1", "argument_2"]
with open(os.devnull, "w") as fnull:
result = subprocess.call(command, stdout = fnull, stderr = fnull)
Если команда не имеет аргументов, вы можете просто указать ее в виде простой строки.
Если ваша команда опирается на такие функции оболочки, как подстановочные знаки, каналы или переменные окружения, вам нужно предоставить всю команду в виде строки, а также указать shell = True
, Этого следует избегать, так как это представляет угрозу безопасности, если содержимое строки не проходит тщательную проверку.
В Python 3.3 и выше, subprocess
поддерживает опцию для перенаправления на/dev/null
, Использовать его при звонке .Popen
а друзья уточни stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
в качестве ключевых аргументов.
Таким образом, ответ DNS, переписанный для Python 3.3+, становится
import subprocess
command = ["executable", "argument_1", "argument_2"]
result = subprocess.call(command,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
Из документации:
subprocess.DEVNULL¶
Специальное значение, которое может использоваться в качестве аргумента stdin, stdout или stderr для Popen и указывает, что будет использоваться специальный файл os.devnull.
Новое в версии 3.3.
Для Python 3.0 до 3.2 вы должны вручную открыть нулевое устройство, используя open(os.devnull)
, как ДНС написал.
Если ваша поисковая система привела вас к этому старому вопросу (как и я), помните, что использование PIPE может привести к тупикам. Действительно, поскольку каналы буферизуются, вы можете записать определенное количество байтов в канал, даже если никто его не читает. Однако размер буфера конечен. И, следовательно, если ваша программа A имеет выход больше буфера, A будет заблокирован при записи, в то время как вызывающая программа B ожидает завершения A. Но нет, в данном конкретном случае... см. Комментарии ниже.
Тем не менее, я рекомендую использовать решение Devin Jeanpierre и DNS.
Как упоминается в документации os.system(), при открытии подпроцесса используйте модуль подпроцесса и, если хотите, установите stdout=open(os.devnull, 'w') (и, возможно, то же самое для stderr).
Я знаю, что уже поздно в игре, но почему бы просто не перенаправить вывод в /dev/null из os.system? Например:
tgt_file = "./bogus.txt"
os.sytem("d2u '%s' &> /dev/null" % tgt_file)
Кажется, это работает в тех случаях, когда вы не хотите иметь дело с подпроцессом.STDOUT.
Если вы не хотите ждать завершения команды, такой как запуск задачи резервного копирования, другой вариант - пропустить ее через bash, что позволяет перенаправлению работать нормально.
Например, запуск звукового файла с помощью aplay:
import os
def PlaySound(filename):
command = 'bash -c "aplay %s &> /dev/null &"' % (filename)
os.system(command)
Таким образом, я могу создать новый процесс, не дожидаясь его завершения, и остановить его печать на терминале. Единственный улов - это то, что он будет загружать экземпляр bash, а также процесс, который вы запускаете, обеспечивая небольшую нагрузку.
Если вам нужно просто захватить STDOUT, не делает ли это присвоение переменной? Например:
megabyte=''
# Create a 1 MiB string of NULL characters.
for i in range(1048576):
megabyte += '\0'
fh=open('zero.bin','w')
# Write an 8 GiB file.
for i in range(8192):
print(i)
# Suppress output of 'write()' by assigning to a variable.
discard=fh.write(megabyte)
fh.close()
Я создавал большой заполненный нулями файл с нулевым свободным пространством на моем жестком диске и обнаружил, что каждый вызов handle.write(string) выплевывает количество записанных байтов. Присвоение этого переменной исключено.
Я использую:
call(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
где команда это строка команды + аргументы
Чтобы это работало, вы должны импортировать подпроцесс