2012-02-24 15 views
0

私は、STDINからPythonスクリプトで読むのに奇妙な問題があります。はSTDINから正しく読み取れません

ここは私の使用例です。 rsyslogが出力モジュールで構成されているので、rsyslogはログメッセージをPythonスクリプトにパイプすることができます。

私のPythonスクリプトは、本当に簡単です:

#! /usr/bin/env python 
# -*- coding: utf-8 -*- 
import sys 

fd = open('/tmp/testrsyslogomoutput.txt', 'a') 
fd.write("Receiving log message : \n%s\n" % ('-'.join(sys.stdin.readlines()))) 
fd.close() 

私はecho "foo" | mypythonscript.pyを実行した場合、私はターゲットファイル/tmp/testrsyslogomoutput.txtに "foo" を得ることができます。しかし、私がrsyslog内でそれを実行すると、メッセージはrsyslogを停止/再開したときにのみ送信されたように見えます(ある時点でいくつかのバッファがフラッシュされると思います)。

まず、Rsyslogに問題があると考えました。だから私はrsyslogの設定に何も変更せずに、シェルのもので私のpythonプログラムを置き換えました。シェルスクリプトは、rsyslogのに完璧に動作し、あなたは以下のコードで見ることができるように、スクリプトは本当に簡単です:

#! /bin/sh 
cat /dev/stdin >> /tmp/testrsyslogomoutput.txt 

私のシェルスクリプトは動作しますが、私のPythonの1がないので、私は私がどこかでミスをしたと信じて私のPythonコードが見つかりませんでした。あなたが私の間違いを指摘することができればそれはすばらしいでしょう。事前に

感謝:)それはファイルの読み込みが完了するまで

答えて

0

私も理由はrsyslogのが終了しないということである疑いがあると思います。 readlines()は実際のEOFに達するまで戻ってはなりません。しかし、シェルスクリプトはなぜ違うのでしょうか?おそらく/ dev/stdinの使用がその理由です。このバージョンを試してみて、それがまだハングせずに実行されている場合参照:オープンし、代わりにsys.stdinをの、のpythonからは/ dev/STDINをお読みください。

#!/bin/sh 
cat >> /tmp/testrsyslogomoutput.txt 

を、これは違いを行った場合、あなたはまた、修正を持っています。

編集:だからcat何とかstdinで待っているものを読み込んで返しますが、pythonはブロックし、stdinが使い果たされるまで待ちます。奇妙な。 readlines()read()と置き換えて、次にsplit("\n")と置き換えてみることもできますが、この時点では役に立ちそうです。

ですから、診断を忘れて、回避策を試してみましょう。stdinに非ブロックI/Oを強制してください。以下は、それを行うことになっている:

import fcntl, os 

# Add O_NONBLOCK to the stdin descriptor flags 
flags = fcntl.fcntl(0, fcntl.F_GETFL) 
fcntl.fcntl(0, fcntl.F_SETFL, fl | os.O_NONBLOCK) 

message = sys.stdin.read().split("\n") # Read what's waiting, in one go 
fd = open('/tmp/testrsyslogomoutput.txt', 'a') 
fd.write("Receiving log message : \n%s\n" % ('-'.join(message))) 
fd.close() 

おそらくpython -uと組み合わせたものを使用したいです。それが動作することを願って!

+0

あなたが提案したことを試しましたが、何の違いもありません。これは、この些細なシェルスクリプトでも完全に機能します。私もpythonスクリプト(readlines()なし)で/ dev/stdinから読み込もうとしましたが、それでもハングします。 –

+0

ああ。次のアイデア:Pythonの-uフラグを付けてpythonを呼び出すことによって、PythonのI/Oバッファリングを式から外します。 – alexis

+0

あなたのサポートのおかげでAlexis、私もpython -uで試して、何も変わっていません。 –

2

readlinesは戻りません。パイプの供給開始が決して終了しないので、readlinesも決して終了しません。 rsyslogを終了すると、パイプが閉じて終了します。

0

readline()を代わりに使用すると、\nに戻りますが、これは1行のみを書き留めて終了します。あなたがいる限り、彼らはそこにある行を書いておきたい場合は

、あなたは簡単なforを使用することができます。

for line in fd: 
    fd.write("Receiving log message : \n%s\n" % (line) 
fd.close() 
+0

私はこれを試しました。問題は同じままです。私はsys.stdinと/ dev/stdinをループしてみました。入力は\ nが送られたときにのみ書かれています。上で示唆したようにreadlineの代わりを使用するとどちらもうまくいきませんでした。 –

関連する問題