python - предотвращать IOError: [Errno 5] Ошибка ввода / вывода при работе без stdout

У меня есть скрипт, который автоматически запускается на сервере через cronjob, и он импортирует и запускает несколько других скриптов.

Некоторые из них используют принты, что естественно создаетIOError: [Errno 5] Input/output error потому что скрипт выполняется без подключения к SSH / терминалу, поэтому нет правильной настройки stdout.

Есть много вопросов на эту тему, но я не смог найти никого, кто на самом делерешать это, при условии, что я не могу удалить печать или изменить выполненные сценарии.

Я пробовал несколько вещей, в том числе:

class StdOut(object):
    def __init__(self):
        pass
    def write(self, string):
        pass
sys.stdout = StdOut()
sys.stderr = StdOut()

а также

from __future__ import print_function
import __builtin__

def print(*args, **kwargs):
        pass
    __builtin__.print = print

Но ничего из этого не работает. Я предполагаю, что это влияет только на сам модуль, а не на модули, которые я импортирую / запускаю позже.

Итак, как я могу создать заглушку stdout, которая повлияет навсе модули в процессе? Как я уже сказал, я не хочу менять скрипты, которые выполняются из основного модуля, но я могу изменить все внутри модуля импорта. И просто, чтобы прояснить - все импортируется, новые процессы не запускаются и т. Д.

Спасибо,

Ответы на вопрос(1)

Решение Вопроса

sys.stdout должен работать (за исключением подпроцессов - но вы исключили их), если вы делаете это достаточно рано. Если нет, то есть трюк с более низким уровнем, который гораздо проще:

запустите ваши сценарии Python с перенаправлением ввода / вывода, которое отбрасывает вывод:

python foo.py >/dev/null 2>&1

(предполагая сценарии Unix-y, как подразумевается "cron" в вопросе)

или перенаправить файловые дескрипторы 1 и 2 (та же идея, что и выше, но это делается при запуске Python, а не как часть команды cron-invoked):

import os
fd = os.open(os.devnull, os.O_RDWR)
# NB: even if stdin is closed, fd >= 0
os.dup2(fd, 1)
os.dup2(fd, 2)
if fd > 2:
    os.close(fd)

(этот конкретный фрагмент кода имеет побочный эффект, заставляя / dev / null действовать как stdin, если все дескрипторы были закрыты). [редактировать: Я начал сwith open(...) а затем переключился наos.open и не тестировал финальную версию. Исправлено сейчас.]

Все это говорит о том, что хороший cron действительно должен иметь где-то подключенные stdout и stderr и отправлять вам выходные данные / сообщения об ошибках по электронной почте. Не все версии cron такие хорошие.

 torek07 июл. 2016 г., 09:26
Первый вариант лучше, так как это означает, что ваша программа может по-прежнему производить нормальный вывод при нормальном запуске.
 Ronen Ness07 июл. 2016 г., 09:13
первое простое решение сделало это для меня. хороший ответ, спасибо! :)

Ваш ответ на вопрос