python stdout刷新和

2024-05-13 03:50:52 发布

您现在位置:Python中文网/ 问答频道 /正文

以下代码在管道插入T形三通时以断管结束,但在未管道插入时行为正确:

#!/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

当管道进入T形管时,观察到的是管道破裂或根本没有输出(T形管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

为什么会这样?


Tags: 代码pylogbin管道usrstdoutsys
3条回答

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

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

(作为旁白,你对日志有什么期望吗?我看不到你的进程输出除了flush on exit之外的任何东西)

不,点击Ctrl-C不会终止两个进程。它只终止tee进程, tee进程的结束将关闭脚本和tee之间的管道,因此脚本将随着断开的管道消息而终止。

为了解决这个问题,tee可以选择将Ctrl-C传递给管道中的前一个进程:-i

试穿:男式T恤

./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

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

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

相关问题 更多 >