我试图捕获在jupyter Notebook中运行命令时打印到STDERR的内容。特别是,我使用的是TensorFlow,它从C部分执行fprintf,该代码通常打印在控制台上,但是我想保存到Python变量中。

我一直在使用来自IPython codebase的FDRedirector,它设置了os.pipe以将输出捕获到Python字符串中。

但是,此代码的问题在于,它会将内核挂起以获取足够大的输出。我怀疑它将挂起超过65k,因为这是Linux上管道缓冲区的大小,并且gdb显示挂起发生在write中。有没有人有适合更大输出的解决方案?

作为我现在正在使用FDRedirector的示例

STDERR = 2
redirect = FDRedirector(STDERR)
import tensorflow as tf
sess = tf.Session("")
node = tf.Print(tf.constant(1), [tf.constant(1)], "longstringlongstring")
def print_to_stderr():
    sess.run(node)   # this prints to stderr
redirect.start();
print_to_stderr()
captured_stderr = redirect.stop()

最后,“captured_stderr”包含打印到stderr的所有内容,包括longstringlongstring。如果使longstring部分更长(> 100k),它将卡住。

最佳答案

您可以尝试将输出管道传输到临时文件-因此没有缓冲区限制:

STDERR=2
STDOUT=1
import os
import sys
import tempfile

class captured:
    def __init__(self, fd=STDERR):
        self.fd = fd
        self.prevfd = None

    def __enter__(self):
        t = tempfile.NamedTemporaryFile()
        print 'Piping your output to ' + t.name
        self.prevfd = os.dup(self.fd)
        os.dup2(t.fileno(), self.fd)
        return t

    def __exit__(self, exc_type, exc_value, traceback):
        os.dup2(self.prevfd, self.fd)

with captured(fd=STDOUT) as tmp:
    os.system('cat 1mbfile.txt');

print "Captured:", open(tmp.name).read()

请让我知道这是否适合您的目的。不幸的是我没有安装TF。

Jupyter自身幸存下来,向一个单元输出1Mb :)

关于python - 使用管道将打印到STDERR的内容捕获到Jupyter的Python变量中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41216215/

10-12 15:52