从python中的sys.stderr读取

时间:2014-09-28 16:42:12

标签: python stderr

关于如何从子进程的stderr和stdout读取,这里有无数的问题。使用当前进程的stderr是否可以这样做?我检查了它并引发了IO错误:文件未打开以供阅读。

我需要阅读stderr并获取数据以便进一步处理。有没有办法以'r +'模式打开文件?

我想到的一种方法是用类似的方法覆盖默认的sys.stderr:

class CustomStdErr(object):
    def write(self, data):
        with open(fakestderr, 'r+') as f:
            f.write(data)

sys.stderr = CustomStdErr()

还有其他方法可以更直接地做到吗?

编辑: 为什么我需要stderr:
代码中有一个与主线程交互的线程(称之为X)(称之为M)。主线程已启用日志记录。这被重定向到stderr。现在,线程X的职责是监视stderr和读取并处理主线程。总之,这是正在发生的事情。

2 个答案:

答案 0 :(得分:2)

嗯,你不能直接做你想做的事。如果一个线程写入默认sys.stderr ,默认情况下它会转到终端,而另一个线程无法读取它。

但是......你总是可以将sys.stderr更改为任何具有write方法的字符串参数的对象(从标准Python库sys模块的文档中提取:< em> stderr不需要是内置文件对象:任何对象都是可接受的,只要它有一个带有字符串参数的write()方法。(更改这些对象不会影响标准I / os模块中由os.popen()os.system()exec*()函数系列执行的进程流。))

简而言之:如果您直接写入sys.stderr,则可以创建一对os.pipe()的管道影响sys.stderr的写入结束,从监控线程读取读取结束 - 仍然可以写入sys.__sterr__或保存的sys.stderr

如果线程启动子进程,请使用subprocess.Popen对象将子命令的stderr流重定向到管道并从监视线程中读取它。

答案 1 :(得分:0)

如果您使用的是* ix并且您拥有互动流程,则可以打开(&#39; / dev / tty&#39;,&#39; r&#39;)。这类似于从stderr读取。请注意,open(&#39; / dev / tty&#34;,&#39; r +&#39;)仅适用于2.x;在3.x中你需要打开(&#39; / dev / tty&#39;,&#39; r&#39;)。