python stdout flush和tee

时间:2009-07-28 09:07:35

标签: python tee

以下代码以管道传输到发球台时以断管结束,但在没有管道时表现正确:

#!/usr/bin/python
import sys
def testfun():
    while 1:
        try :
            s = sys.stdin.readline()
        except(KeyboardInterrupt) :
            print('Ctrl-C pressed')
            sys.stdout.flush()
            return
        print s

if __name__ == "__main__":
    testfun()
    sys.exit()

预期产出:

./bug.py 
Ctrl-C pressed

当管道输入管道时管道是管道坏了还是根本没有输出,即tee stdout上没有任何内容,而bug.log中没有任何内容:

./bug.py | tee bug.log
Traceback (most recent call last):
  File "./bug.py", line 14, in <module>
    sys.stdout.flush()
IOError: [Errno 32] Broken pipe

这可能是什么原因?

3 个答案:

答案 0 :(得分:9)

不,按Ctrl-C不会终止这两个进程。它只终止了T恤过程, tee进程结束时关闭脚本和tee之间的管道,因此你的脚本会因破坏的管道消息而死亡。

要解决此问题,tee可以选择将Ctrl-C传递给管道中的上一个进程:-i

尝试:男人发球

./bug.py
^CCtrl-C pressed
./bug.py | tee log
^CTraceback (most recent call last):
  File "./bug.py", line 14, in <module>
    testfun()
  File "./bug.py", line 9, in testfun
    sys.stdout.flush()
IOError: [Errno 32] Broken pipe

./bug.py | tee -i log
^CCtrl-C pressed

答案 1 :(得分:5)

这不是一个python问题,而是一个shell问题,正如Brian指出的那样,按Ctrl-C将终止这两个进程。解决方法是使用命名管道:

mknod mypipe p
cat mypipe | tee somefile.log &
./bug.py > mypipe

答案 2 :(得分:3)

当您点击Ctrl-C时,shell将终止两个进程(pythontee)并拆除连接它们的管道。

因此,当您在python进程中处理Ctrl-C并刷新时,它会发现tee已被终止且管道已不再存在。因此错误信息。

(顺便说一下,你会期待日志中的任何内容吗?我看不到你的进程在退出时输出除了刷新之外的其他内容)