質問

次のコードは、ティーに配管されたときに壊れたパイプで終わりますが、配管されていないときは正しく動作します。

#!/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にヒットすると、シェルが終了します 両方 プロセス(pythontee)そして、それらを接続するパイプを取り壊します。

したがって、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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top