質問
次のコードは、ティーに配管されたときに壊れたパイプで終わりますが、配管されていないときは正しく動作します。
#!/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
ティーにパイプされたときに観察されるのは、パイプが壊れているか、出力がまったくないこと、つまりティーセットでは何も、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
これの理由は何ですか?
解決
Ctrl-Cにヒットすると、シェルが終了します 両方 プロセス(python
と tee
)そして、それらを接続するパイプを取り壊します。
したがって、CTRL-Cを処理するとき python
プロセスとフラッシュ、それはそれを見つけるでしょう tee
終了し、パイプはもうありません。したがって、エラーメッセージ。
(余談ですが、ログに何かを期待しますか?出口のフラッシュ以外のプロセスが出力されているとは思わない)
他のヒント
いいえ、CTRL-Cを打つことは両方のプロセスを終了しません。 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
これはPythonの問題ではなく、Brianが指し示しているように、Ctrl-Cを打つようにシェルの問題であり、両方のプロセスを終了します。回避策は、名前付きパイプを使用することです。
mknod mypipe p
cat mypipe | tee somefile.log &
./bug.py > mypipe
所属していません StackOverflow