ファイル値が変更されました[閉じる]

ファイル値が変更されました[閉じる]

ファイルが変更されたかどうかを検出するためにpyinotifyを使用しようとしています。

そうしてみてください

def status(argument):
    global email_alarm_status
    global new_email_alarm

    if not email_alarm_status:
        with open('pathtofile') as fp:
            email_alarm_status = fp.read()
        with open("pathtofile","w") as cp:
            cp.write(email_alarm_status)

    with open('pathtofile') as fp:
        with open("pathtofile") as cp:
            if cp.read() != fp.read():
                print "changed"
                email_alarm_status = fp.read()


wm = pyinotify.WatchManager()
notifier = pyinotify.Notifier(wm)
wm.add_watch('pathtofile', pyinotify.IN_MODIFY)   
notifier.loop(callback=status)

値が変わると「通知」します。これで問題は、notifier.loopがイベントに関する情報を印刷して「オフ」を試み、次のようにstdoutを少し開いてみました。

class NullDevice():
    def write(self, s):
        pass

original_stdout = sys.stdout  # keep a reference to STDOUT
sys.stdout = NullDevice()  # redirect the real STDOUT
print "2 - this won't print"
sys.stdout = original_stdout  # turn STDOUT back on
print "3 - this will print to SDTDOUT"
wm = pyinotify.WatchManager()
notifier = pyinotify.Notifier(wm)
wm.add_watch('/home/pi/socketserver/var', pyinotify.IN_MODIFY)
sys.stdout = f

notifier.loop(callback=status)

sys.stdout = original_stdout  # turn STDOUT back on
print "3 - this will print to SDTDOUT"

しかし、うまくいきません。 pyinotifyからエラーを返します...

pi@TestEnv:~ $ python ./python/handler
Traceback (most recent call last):
  File "./python/handler", line 83, in <module>
    notifier.loop(callback=status)
  File "/usr/local/lib/python2.7/dist-packages/pyinotify.py", line 1390, in loop
    self.process_events()
  File "/usr/local/lib/python2.7/dist-packages/pyinotify.py", line 1287, in process_events
    self._default_proc_fun(revent)
  File "/usr/local/lib/python2.7/dist-packages/pyinotify.py", line 924, in __call__
    return _ProcessEvent.__call__(self, event)
  File "/usr/local/lib/python2.7/dist-packages/pyinotify.py", line 650, in __call__
    return self.process_default(event)
  File "/usr/local/lib/python2.7/dist-packages/pyinotify.py", line 982, in process_default
    self._out.flush()
AttributeError: NullDevice instance has no attribute 'flush'

なぜこれを知っている人がいますか?それとも、ファイルが変更された場合に機能を実装する方法はありますか?

ベストアンサー1

sys.stdoutをこのように変更することはできません。テキストIOラッパー実際には、ファイル記述子1の実際の標準出力の周りです。その結果、同様のものprint(またはファイル記述子1に直接書き込まれたもの)は、現在実行中の操作を完全に無視します。真のリダイレクトを達成するには、次のことを行う必要があります。

# Copy standard out to a second file descriptor for restoration
original_stdout = os.dup(sys.stdout.fileno())

# Replace standard out with /dev/null
nullfd = os.open("/dev/null", os.O_WRONLY)
os.dup2(nullfd, sys.stdout.fileno())
os.close(nullfd)

# Do your stuff here

# Restore standard out and close duplicated file descriptor
os.dup2(original_stdout, sys.stdout.fileno())
os.close(original_stdout)

これにより、すべての標準出力が/ dev / nullにリダイレクトされ、完了すると再び復元されます。バラよりos.dupのドキュメントオペレーティングシステム dup2そしてCで標準ファイル記述子をリダイレクトする方法に関するこのStackOverflowドキュメント(Pythonにも同じ原則が適用されます。)

os組み込みの機能ではなく、ここで関数を使用する必要があることに注意してくださいopen。これを行うには、実際のデフォルトのファイル記述子を使用する必要があります。

おすすめ記事