文件的值已更改

文件的值已更改

我正在尝试使用 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'

有人知道这是为什么吗?或者有什么方法可以实现 if 文件已更改功能?

答案1

你不能像这样修改 sys.stdout ; 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.您必须使用实际的底层文件描述符才能使其工作。

答案2

当您创建通知程序时:

notifier = pyinotify.Notifier(wm)

您可以传递处理该事件的第二个参数。默认情况下,处理程序打印事件。要阻止这种情况,请创建您自己的不执行任何操作的最小处理程序。例如:

class NoLog(pyinotify.ProcessEvent):
    def process_default(self, event):
        pass

handler = NoLog()
notifier = pyinotify.Notifier(wm, default_proc_fun=handler)

处理事件

相关内容