python - 防止 IOError: [Errno 5] 在没有标准输出的情况下运行时输入/输出错误 [英] python - prevent IOError: [Errno 5] Input/output error when running without stdout

查看:43
本文介绍了python - 防止 IOError: [Errno 5] 在没有标准输出的情况下运行时输入/输出错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个通过 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆