python - 防止 IOError: [Errno 5] 在没有标准输出的情况下运行时输入/输出错误 [英] python - prevent IOError: [Errno 5] Input/output error when running without stdout
问题描述
我有一个通过 cronjob 在服务器上自动运行的脚本,它导入并运行其他几个脚本.
I have a script that runs automatically on server through cronjob and it import and run several other scripts.
其中一些使用打印,这自然会产生 IOError: [Errno 5] 输入/输出错误
,因为脚本在没有任何 SSH/终端连接的情况下运行,因此没有正确的标准输出设置.
Some of them use prints, which naturally creates IOError: [Errno 5] Input/output error
because the script runs without any SSH / terminal connected, so there's no proper stdout setup.
关于这个主题有很多问题,但我找不到真正解决它的人,假设我无法删除打印或更改执行的脚本.
There are lots of questions about this subject but I couldn't find anyone that actually solve it, assuming I can't remove the print or change the executed scripts.
我尝试了几件事,包括:
I tried several things, including:
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
但是都没有效果.我认为它只影响模块本身,而不影响我稍后导入/运行的模块.
But none of it works. I assume it only affect the module itself and not the modules I import / run later.
那么我如何创建一个存根标准输出来影响流程中的所有模块?就像我说的,我不想更改从主模块执行的脚本,但我可以更改导入模块中的所有内容.并且只是为了澄清 - 一切都被导入,没有产生新的进程等等.
So how can I create a stub stdout that will affect all modules in the process? Like I said, I don't want to change the scripts that are executed from the main module, but I can change everything inside the importing module. And just to clearify - everything is imported, no new processes are spawned etc.
谢谢,
推荐答案
修改内置程序或更改 sys.stdout
应该 工作(子进程除外——但你规定了那些出),只要你做得够早.如果没有,那么还有一个更简单的低级技巧:
Modifying the builtin or changing sys.stdout
should work (except for subprocesses—but you ruled those out) as long as you do it early enough. If not, though, there's a lower level trick that's much easier:
使用丢弃输出的 I/O 重定向运行您的 Python 脚本:
run your python scripts with I/O redirection that discards output:
python foo.py >/dev/null 2>&1
(假设 Unix-y 脚本,正如问题中的cron"所暗示的那样)
(assuming Unix-y scripts, as implied by "cron" in the question)
或者,重定向文件描述符 1 和 2(与上面的想法相同,但在 Python 启动时完成,而不是作为 cron 调用命令的一部分):
or, redirect file descriptors 1 and 2 (same idea as above, but done within your Python startup rather than as part of the cron-invoked command):
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 充当标准输入的副作用).[编辑:我从 with open(...)
开始,然后切换到 os.open
并没有测试最终版本.现已修正.]
(this particular bit of code has the side effect of making /dev/null act as stdin, if all descriptors were closed). [Edit: I started with with open(...)
and then switched to os.open
and did not test the final version. Fixed now.]
综上所述,一个好的 cron 确实应该在某处连接 stdout 和 stderr,并且应该通过电子邮件将输出/错误输出发送给您.不过,并非所有的 cron 版本都这么好.
All that said, a good cron really should have stdout and stderr connected somewhere, and should email the output/error-output to you. Not all cron versions are this nice though.
这篇关于python - 防止 IOError: [Errno 5] 在没有标准输出的情况下运行时输入/输出错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!