Подавить стандартный вывод из check_output, но вместо этого записать его в журнал - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть следующий код:

try:
    subprocess.check_output(command.split())
except subprocess.CalledProcessError as e:
    count_failure.increment()
    logger.error(e.__dict__)
    return

Когда check_output() не удается, я хотел бы подавить это сообщение из stdout, но вместо этого записать его в мой logger.

Прямо сейчас сообщение об ошибке stdout портит мой tqdm индикатор выполнения:

[hobbes3@hobbes3 bin]$ ./mass_index.py
34%|█████████████████████████████████████████▋                                                                                | 13/38 [00:00<00:14,  1.75it/s]
unable to open file: path='/mnt/data/samples/irs_990/foo.xml' error='Permission denied'
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 38/38 [00:02<00:00,  5.96it/s]

Кроме того, фактическое сообщение Permission denied не сохраняется внутри e.Мой e.__dict__ только говорит

{'returncode': 22, 'cmd': ['/opt/splunk/bin/splunk', 'add', 'oneshot', '/mnt/data/samples/irs_990/foo.xml', '-index', 'main', '-sourcetype', 'irs_990'], 'output': b'', 'stderr': None}

1 Ответ

0 голосов
/ 07 декабря 2018

, потому что команда, которую вы запускаете, выдает сообщения об ошибках в стандартный поток ошибок.

check_output захватывает только стандартный вывод , если только вы не используете дополнительный параметр.Так что либо:

subprocess.check_output(command.split(),stderr=subprocess.STDOUT)

, поэтому ошибки также выводятся, либо (python 3):

subprocess.check_output(command.split(),stderr=subprocess.DEVNULL)

для полного подавления этого сообщения об ошибке.

Чтобы получитьПравильное сообщение об исключении со стандартной ошибкой, вы должны будете перенаправить поток ошибок в конкретный канал, чтобы у вас не было stderr=None

subprocess.check_output(command.split(),stderr=subprocess.PIPE)

Но это могло бы вызвать взаимные блокировки между выходными потоками и потоками ошибок (в зависимости от того, как программа выводит на выход или на ошибку, если каналы не читаются умным способом (например, с многопоточностью), одна запись может блокироваться из-за переполнения буфера, пока вы читаете другую, которая пуста).

Может быть, в вашем случае вам лучше использовать subprocess.Popen и communicate, которые прекрасно справляются с этим делом (с потоками или чем-то еще, что работает под ним)

p = subprocess.Popen(command.split(),stderr=subprocess.PIPE,stdout=subprocess.PIPE)
output,error = p.communicate()

(и сохраняйтета же обработка исключений)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...