研究笔记:Linux下文件监控模块
模块
主要想实现功能是监测文件夹,如果有新的文件了,就把它上传
inotify
因为我想用Python写,所以我主要研究了pyinotify
Document
一些资料
我想要的功能基本都有(e.g:复制完成后再进行操作用IN_CLOSE_WRITE
)
但是难受的是不能跨服务器监测,只能监测本地的操作。监测共享文件会没反应,伤心。
一个小例子:
import pyinotify
class TestEventHandler(pyinotify.ProcessEvent):
def process_IN_CREATE(self, event):
print('IN_CREATE ',event.pathname)
def process_IN_CLOSE_WRITE(self, event):
print('IN_CLOSE_WRITE ',event.pathname)
wm = pyinotify.WatchManager()
event = pyinotify.IN_CREATE | pyinotify.IN_CLOSE_WRITE
wm.add_watch('/watchfolder', events, rec=True, auto_add=True) # rec:是否监测子文件价,auto_add:是否把新建的子文件夹自动添加到监测列表中
handler = TestEventHandler(corpusManager)
notifier = pyinotify.Notifier(wm, handler)
notifier.loop()
Systemd Path Units
一个介绍
优点是简单方便,不用特地去装什么包,但是缺点就是,延展性不强,就这几种状态,想做复杂点操作就不行了。以及这个主要还是基于inotify 的,所以inotify遇到的问题这个也会有,不能跨服务器,并且如果两个操作时间过于近可能会出现后一个丢失的问题。
一个小例子:
简单来说要有3个脚本:
一个是你监测到文件变化需要进行操作的脚本(test.py
)或者直接是一个应用程序
还有一个是执行这个脚本(test.py
)的systemd文件(filemonitor_event.service
)
[Unit]
Description="Run script to send email alert"
[Service]
ExecStart=/usr/bin/python /usr/local/test.py #需要是完整路径
最后是一个用来监测的systemd文件(unit_file.path
)
[Unit]
Description="Monitor the /etc/passwd file for changes"
[Path]
PathModified=/etc/passwd # 监测路径
Unit=passwd-mon.service
[Install]
WantedBy=multi-user.target
其中PathModified 是监测文件的状态,可以换成PathExists、 PathExistsGlob、PathChanged 、PathModified、DirectoryNotEmpty
后两个文件(filemonitor_event.service, unit_file.path
)需要放在 /etc/systemd/system/ 下面
watchdog
用的也是python种的一个模块,
官方文档
import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
path = sys.argv[1] if len(sys.argv) > 1 else '.'
event_handler = LoggingEventHandler()
observer = Observer()
observer.schedule(event_handler, path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
如果需要进行操作的话就写个类来继承,比如
class FileEventHandler(FileSystemEventHandler):
def on_created(event):
print("create a new file")
将from watchdog.observers import Observer
换成from watchdog.observers.polling import PollingObserver
就可以完美的解决解决跨平台的问题,但是上传又有一点问题。它的触发机制全都是会触发,没有区分事件完成前触发还是完成后触发,我如果想做有新文件就上传这个功能,就不能保证文件复制结束后再上传,看了好多资料 这个比较文件大小的方法感觉不是很好但是也能完成我的需求
copying = True
size2 = -1
while copying:
size = os.path.getsize('name of file being copied')
if size == size2:
break
else:
size2 = os.path.getsize('name of file being copied')
总结
综上所述,我最后选择了watchdog,但是我的所有测试都是基于linux的没有测试跨平台会不会有问题。