現在、Linuxシステムのpythonでプログラムを作成しています。目的は、ログファイルを読み取り、特定の文字列を見つけたらbashコマンドを実行することです。ログファイルは常に書き込まれています。私の質問は:
Open()メソッドを使用してファイルを開くと、Pythonファイルオブジェクトは、実際のファイルが他のプログラムによって書き込まれるときに更新されますか、または一定の間隔でファイルを再度開く必要がありますか?
ありがとう
ジム
更新:これまでの回答をありがとう。おそらく、ファイルはJava EEアプリによって書き込まれているので、データが書き込まれるタイミングを制御することはできません。現在、ファイルを再オープンするプログラムがあります。 10秒ごとに、最後に読み取ったファイルのバイト位置から読み取ろうとします。現時点では、返された文字列を出力するだけです。ファイルを再度開く必要はありませんが、読み取りコマンドはJavaアプリによってファイルに書き込まれたデータに何らかの方法でアクセスできます。
#!/usr/bin/python
import time
fileBytePos = 0
while True:
inFile = open('./server.log','r')
inFile.seek(fileBytePos)
data = inFile.read()
print data
fileBytePos = inFile.tell()
print fileBytePos
inFile.close()
time.sleep(10)
Pyinotifyとジェネレーターに関するヒントをありがとう。より良い解決策として、これらを見ていきます。
David Beazleyの Pythonのジェネレータートリック 、特にパート5:無限データの処理を参照することをお勧めします。 Python tail -f logfile
コマンドをリアルタイムで。
# follow.py
#
# Follow a file like tail -f.
import time
def follow(thefile):
thefile.seek(0,2)
while True:
line = thefile.readline()
if not line:
time.sleep(0.1)
continue
yield line
if __== '__main__':
logfile = open("run/foo/access-log","r")
loglines = follow(logfile)
for line in loglines:
print line,
「対話型セッションは1000語に相当します」
>>> f1 = open("bla.txt", "wt")
>>> f2 = open("bla.txt", "rt")
>>> f1.write("bleh")
>>> f2.read()
''
>>> f1.flush()
>>> f2.read()
'bleh'
>>> f1.write("blargh")
>>> f1.flush()
>>> f2.read()
'blargh'
言い換えれば、はい、単一の「オープン」で十分です。
以下は Jeff Bauer answerのわずかに修正されたバージョンで、ファイルの切り捨てに耐性があります。ファイルがlogrotate
によって処理されている場合に非常に便利です。
import os
import time
def follow(name):
current = open(name, "r")
curino = os.fstat(current.fileno()).st_ino
while True:
while True:
line = current.readline()
if not line:
break
yield line
try:
if os.stat(name).st_ino != curino:
new = open(name, "r")
current.close()
current = new
curino = os.fstat(current.fileno()).st_ino
continue
except IOError:
pass
time.sleep(1)
if __== '__main__':
fname = "test.log"
for l in follow(fname):
print "LINE: {}".format(l)
Whileループで実行されているファイルを読み取るコードがある場合:
f = open('/tmp/workfile', 'r')
while(1):
line = f.readline()
if line.find("ONE") != -1:
print "Got it"
また、別のプログラムから同じファイルに(追加モードで)書き込んでいます。ファイルに「ONE」が追加されるとすぐに、印刷されます。あなたがしたいことは何でもできます。つまり、定期的にファイルを再度開く必要はありません。
>>> f = open('/tmp/workfile', 'a')
>>> f.write("One\n")
>>> f.close()
>>> f = open('/tmp/workfile', 'a')
>>> f.write("ONE\n")
>>> f.close()
私はここでは専門家ではありませんが、何らかのオブザーバーパターンを使用してファイルを受動的に監視し、変更が発生したときにファイルを再度開くイベントを発生させる必要があると思います。これを実際に実装する方法については、私にはわかりません。
あなたが提案するようにopen()がリアルタイムでファイルを開くとは思いません。