2017-08-04 145 views
1

看过其他stackoverflow帖子后,我似乎无法找出这个重定向问题。我想要做的是压制stdout和stderr,然后在捕获错误之后恢复它们。压制工作正常,但恢复他们只有一半作品。如果我试图压制并恢复stderr和stdout,那么压制就会起作用,但不会恢复。如果我只是试图压制/恢复标准输出它可以工作(但是我得到了所有我不想要的标准输入文本)。我无法推断为什么会有任何差异导致stderr阻止标准输出恢复,希望为什么可能是(或如果我做的事情奇怪/愚蠢)输入

继承人的代码,我想工作,但只抑制了/犯错,也不会恢复(“恢复标准输出”从不打印):恢复重定向sys.stdout和sys.stderr产生奇怪的结果

sys.stdout = None 
sys.stderr = None 
try: 
    op_args = op_parse.parse_args(selection.split(' ')) 
except SystemExit: 
    sys.stdout = sys.__stdout__ 
    sys.stderr = sys.__stderr__ 
    print("Restored stdout") 


继承人抑制stdout和恢复它(在印刷讨厌的标准错误的成本)的代码

sys.stdout = None 
#sys.stderr = None 
try: 
    op_args = op_parse.parse_args(selection.split(' ')) 
except SystemExit: 
    sys.stdout = sys.__stdout__ 
    #sys.stderr = sys.__stderr__ 
    print("Restored stdout") 

编辑:我想了一个窝周围,​​但我仍然对上述问题发生的原因感兴趣。我的工作是将stdout/stderr重新分配给= open(“/ dev/null”,“w”),它产生了我想要的行为。再次,我仍然想对原始问题的输入

回答

0

作为一个高层次的评论,这种技术是容易出错,通常意味着其他事情出错了。例如 - 在上面的except中恢复(而不是在finally中)意味着如果失败,则恢复stdout和stderr 只有

我怀疑你观察到的问题可能是由于你的op_parse调用。考虑下面的代码

from __future__ import print_function 
import sys 

sys.stdout = None 
sys.stderr = None 
try: 
    print('before', file=sys.stdout) 
    print('before', file=sys.stderr) 
    # sys.stderr.write('hi') 
    assert False 
except AssertionError: 
    sys.stdout = sys.__stdout__ 
    sys.stderr = sys.__stderr__ 
    print("Restored stdout", file=sys.stdout) 

当我运行它时,我看到:Restored stdout

如果我取消注释sys.stderr.write一行,我看到:lost sys.stderr

一个更安全的方法是使用上下文到stdout/ERR重定向到/dev/null或您的操作过程中IOStream - 或者更好的是,找到验证功能正在内部使用和调用,而不是直接寻找一个系统的出口上更高级的功能(是op_parse == opt_parse?)

+0

感谢您的意见,我同意恢复需要发生在finally块中,在这个测试程序中我每次都故意给它一个错误,所以我没有打扰。在看到此消息之前,我发现了“/ dev/null”技巧,所以我可以确认您的解决方案是否有效。 (也op_parse不是opt_parse它只是一个不好的变量名称来代表'选项解析') – sliceOfPi

2

您可以通过创建一个上下文管理典雅的做多这一点:

import os 
from contextlib import contextmanager 

@contextmanager 
def nullout(): 
    save_stdout = sys.stdout 
    save_stderr = sys.stderr 
    sys.stdout = open(os.devnull, 'w') 
    sys.stderr = open(os.devnull, 'w') 
    yield 
    sys.stdout = save_stdout 
    sys.stderr = save_stderr 

with nullout(): 
    op_args = op_parse.parse_args(selection.split(' ')) 

关于上下文管理一个很好的事情是,yield后的代码将得到执行不管是否异常发生与否。

的原因,你不能只设置sys.stdoutsys.stderrNone可能是因为None没有write()close()方法,一般不会表现得像一个输出流。