Я унаследовал некоторый код, который периодически (случайно) не работает из-за ошибки ввода/вывода, возникающей во время вызова для печати. Я пытаюсь определить причину возникновения исключения (или, по крайней мере, лучше понять его) и как правильно его обрабатывать.
При выполнении следующей строки Python (в интерпретаторе 2.6.6, работающем на CentOS 5.5):
print >> sys.stderr, 'Unable to do something: %s' % command
Исключено (исключение трассировки):
IOError: [Errno 5] Input/output error
В контексте, как правило, это то, что большая функция пытается сделать в то время:
from subprocess import Popen, PIPE
import sys
def run_commands(commands):
for command in commands:
try:
out, err = Popen(command, shell=True, stdout=PIPE, stderr=PIPE).communicate()
print >> sys.stdout, out
if err:
raise Exception('ERROR -- an error occurred when executing this command: %s --- err: %s' % (command, err))
except:
print >> sys.stderr, 'Unable to do something: %s' % command
run_commands(["ls", "echo foo"])
Синтаксис >>
не очень мне знаком, это не то, что я часто использую, и я понимаю, что это, пожалуй, написания STDERR. Однако я не считаю, что альтернативы будут устранять основную проблему.
Из документации, которую я прочитал, IOError 5 часто неправильно используется и несколько слабо определен, при этом различные операционные системы используют его для решения различных проблем. Самое лучшее, что я вижу в моем случае, это то, что процесс python больше не привязан к терминалу /pty.
Насколько я могу сказать, ничто не отключает процесс от потоков stdout/stderr - терминал по-прежнему открыт, например, и все "отображается" в порядке. Может ли это быть вызвано тем, что дочерний процесс заканчивается нечистым образом? Что еще может быть причиной этой проблемы - или какие другие шаги я могу внести, чтобы отладить ее дальше?
Что касается обработки исключения, я, очевидно, поймаю его, но я предполагаю, что это означает, что я не смогу напечатать на stdout/stderr для остальной части исполнения? Могу ли я снова подключиться к этим потокам - возможно, сбросив sys.stdout
до sys.__stdout__
и т.д.? В этом случае невозможность записи в stdout/stderr не считается фатальной, но если это указывает на то, что что-то начинает идти не так, я бы предпочел залог раньше.
Я предполагаю, что в конечном итоге я немного потеряю, где начать отладку этого...