inotify是内核自带的监控文件变动的工具。当然,要使用还是要安装命令行工具inotify-tools
。
但是和cron不同的是,inotify并没有作为可以开机启动的服务。所以必须由脚本启动。
systemd
为了和rc.local
体系兼容,也为了方便以后添加需要开机运行的命令,所以自己写一个开机运行/etc/rc.local
的systemd服务/etc/systemd/system/rc-local.service
。
[Unit]
Description=/etc/rc.local Compatibility
After=iptables.service syslog-ng.service
[Service]
Type=oneshot
ExecStart=/etc/rc.local
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
需要注意的是Type=oneshot
。因为inotify的监控脚本需要一直在后台运行,所以rc-local.service
需要允许/etc/rc.local
fork,而Type=simple
是不允许fork的,所以使用oneshot模式。
添加rc-local.service到systemd后,开机就会由systemd以root执行/etc/rc.local
。
inotify
再次新建一个可执行脚本,my_inotify.sh
,这就是真正的用来监控目录的脚本了。
#!/bin/bash
while /usr/bin/inotifywait -sr -e attrib,modify,create,delete "${1}"
do
## WHATEVER YOU WANT TO DO
done
这个脚本会一直循环,但是只有当inotifywait
返回结果时,才会执行DO
里面的命令,在这个命令运行结束后,再次运行inotifywait
并等待结果。
inotifywait
会在监控目录有attrib,modify,create,delete
事件时返回结果,否则就一直等待。
所以,只有当事件发生时才会执行一次循环,而事件不发生时循环处于等待inotify的状态,并不耗费系统资源。由于inotify只会运行一次,事件发生后就退出了,所以需要循环在事件发生以后再次执行inotify并等待下一次事件发生。
需要注意的是inotifywait
不可以以-m
或者-d
模式运行,因为这两种模式都不会返回结果,所以循环也就不会执行了。
rc.local
接下来就要建立一个可执行的/etc/rc.local
。
#!/bin/bash
full_path_to_my_inotify_script.sh dir_to_watch &