在复制文件描述符时何时调用flush()?

时间:2013-03-30 15:35:48

标签: python io-redirection torque

当我调用python python-wrapped C ++时,我有一个重定向输出的包装器。

基本思想是使用dupdup2,这是我能够从C ++中捕获printf输出的唯一方法。只要我以交互方式运行作业,包装器就可以正常工作而不需要调用flush(),但是当我将作业发送到TORQUE批处理时,我再次获得了不受欢迎的输出。

我的理解,部分来自this question,是一些有条不紊的flush()来电应该解决这个问题,但他们究竟应该去哪里?我应该在重复之前将缓冲区刷新到tempfile吗?在重复之前?都?


我使用的包装如下:

class Filter(object): 
    """
    Workaround filter for annoying and worthless errors. 
    """
    def __init__(self, veto_words={'ClassTable'}): 
        self.veto_words = set(veto_words)
        self.temp = tempfile.NamedTemporaryFile()
    def __enter__(self): 
        sys.stdout.flush() # <--- NEEDED? 
        sys.stderr.flush() # <--- NEEDED? 
        self.old_out, self.old_err = os.dup(1), os.dup(2)
        os.dup2(self.temp.fileno(), 1)
        os.dup2(self.temp.fileno(), 2)
    def __exit__(self, exe_type, exe_val, tb): 
        sys.stdout.flush() # <--- NEEDED? 
        sys.stderr.flush() # <--- NEEDED? 
        os.dup2(self.old_out, 1)
        os.dup2(self.old_err, 2)
        self.temp.seek(0)
        for line in self.temp: 
            veto = set(line.split()) & self.veto_words
            if not veto: 
                sys.stderr.write(line)

1 个答案:

答案 0 :(得分:2)

Python在连接到TTY时应用行缓冲,否则需要更大的缓冲区。

将Python程序重定向到管道意味着没有连接到流的TTY,即使在发送换行符时也必须使用.flush()

您可以使用-u运行Python来关闭stdout的缓冲。