当管道输入三通时,以下代码以断管结束,但在未通过管道传输时表现正常:
#!/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()
Run Code Online (Sandbox Code Playgroud)
预期产量:
./bug.py
Ctrl-C pressed
Run Code Online (Sandbox Code Playgroud)
当管道输入三通时,观察到的是管道损坏或根本没有输出,即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
Run Code Online (Sandbox Code Playgroud)
这可能是什么原因?
小智 9
不,按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
Run Code Online (Sandbox Code Playgroud)
这不是一个python问题,而是一个shell问题,正如Brian指出的那样,按Ctrl-C将终止这两个进程.解决方法是使用命名管道:
mknod mypipe p
cat mypipe | tee somefile.log &
./bug.py > mypipe
Run Code Online (Sandbox Code Playgroud)