linux实时文件事件监听--inotify

简介: 一、inotify简介 inotify是Linux内核2.6.13 (June 18, 2005)版本新增的一个子系统(API),它提供了一种监控文件系统(基于inode的)事件的机制,可以监控文件系统的变化如文件修改、新增、删除等,并可以将相应的事件通知给应用程序。

一、inotify简介

inotify是Linux内核2.6.13 (June 18, 2005)版本新增的一个子系统(API),它提供了一种监控文件系统(基于inode的)事件的机制,可以监控文件系统的变化如文件修改、新增、删除等,并可以将相应的事件通知给应用程序。该机制由著名的桌面搜索引擎项目beagle引入用于替代此前具有类似功能但存在诸多缺陷的dnotify。

inotify既可以监控文件,也可以监控目录。当监控目录时,它可以同时监控目录及目录中的各子目录及文件的。此外,inotify 使用文件描述符作为接口,因而可以使用通常的文件I/O操作select、poll和epoll来监视文件系统的变化。

inotify 可以监视的文件系统常见事件包括:

IN_ACCESS:文件被访问
IN_MODIFY:文件被修改
IN_ATTRIB,文件属性被修改
IN_CLOSE_WRITE,以可写方式打开的文件被关闭
IN_CLOSE_NOWRITE,以不可写方式打开的文件被关闭
IN_OPEN,文件被打开
IN_MOVED_FROM,文件被移出监控的目录
IN_MOVED_TO,文件被移入监控着的目录
IN_CREATE,在监控的目录中新建文件或子目录
IN_DELETE,文件或目录被删除
IN_DELETE_SELF,自删除,即一个可执行文件在执行时删除自己
IN_MOVE_SELF,自移动,即一个可执行文件在执行时移动自己

 

通过/proc接口中的如下参数设定inotify能够使用的内存大小:
1、/proc/sys/fs/inotify/max_queue_events
应用程序调用inotify时需要初始化inotify实例,并时会为其设定一个事件队列,此文件中的值则是用于设定此队列长度的上限;超出此上限的事件将会被丢弃;
2、/proc/sys/fs/inotify/max_user_instances
此文件中的数值用于设定每个用户ID(以ID标识的用户)可以创建的inotify实例数目的上限;
3、/proc/sys/fs/inotify/max_user_watches
此文件中的数值用于设定每个用户ID可以监控的文件或目录数目上限;


二、inotify-tools

inotify是一个API,需要通过开发应用程序进行调用,对于大多数用户来讲这有着许多不便,inotify-tools的出现弥补了这一不足。inotify-tools是一套组件,它包括一个C库和几个命令行工具,这些命令行工具可用于通过命令行或脚本对某文件系统的事件进行监控。它由Rohan McGovern开发,其项目网址为http://inotify-tools.sourceforge.net。

inotify-tools提供的两个命令行工具:
inotifywait:通过inotify API等待被监控文件上的相应事件并返回监控结果,默认情况下,正常的结果返回至标准输出,诊断类的信息则返回至标准错误输出。它可以在监控到对应监控对象上指定的事件后退出,也可以进行持续性的监控。
inotifywatch:通过inotify API收集被监控文件或目录的相关事件并输出统计信息。


inotifywait命令使用简介:
inotifywait尤其适用于在脚本中等待某事件的发生,并可基于特定的事件执行相应操作。如将其用于脚本中监控某指定目录中的文件上的修改、新建、删除、属性信息的改变,而后使用rsync命令将某事件对应的文件同步至其它主机上。其常用选项如下:
-m, --monitor:inotifywait的默认动作是在监控至指定文件的特定事件发生一次后就退出了,而使用此选项则可实现持续性的监控;
-r, --recursive:递归监控指定目录下的所有文件,包括新建的文件或子目录;如果要监控的目录中文件数量巨大,则通常需要修改/proc/sys/fs/inotify/max_users_watchs内核参数,因为其默认值为8192。
-e , --event :指定要监控的特定事件,默认是监控所有的事件;此处包括access, modify, attrib, close_write, close_nowirte, close, open, moved_to, moved_from, move, create, delete, delete_selt等;
--timefmt :当在--format选项中使用%T时,--timefrt选项则可以用来指定自定义的符合strftime规范的时间格式,此时间格式可用的格式符可以通过strftime的手册页获取;--timefrt后常用的参数是'%d/%m/%y %H:%M';
--format :自定义inotifywait的输出格式,如--format '%T %w %f';常用的格式符如下:
%w:显示被监控文件的文件名;
%f:如果发生某事件的对象是目录,则显示被监控目录的名字;默认显示为空串;
%T:使用--timefmt选项中自定义的时间格式;

例如,要监控/tmp/test目录及其内部所有文件上发生的create,delete,modify,close_write事件,则使用如下命令:
# inotify -r --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' -e create,delete,modify,close_write /tmp/test

此命令在监控到某文件上第一次事件后就会退出,如果想一直监控,则需要为命令添加-m选项。

在很多场景中都会用到将某主机上的某目录下的所有文件改变实时同步至另一主机上的指定位置,这也可以通过在脚本中使用inotifywait结合rsync命令来实现,比如如下脚本:

#!/bin/bash

DESTHOST=172.16.100.6
DESTHOSTDIR=/www/htdocs/
SRCDIR=/www/htdocs/

inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' \
-e create,delete,modify,attrib $SRCDIR | while read DATE TIME DIR FILE; do
$FILECHANGE=${DIR}${FILE}

rsync -avze 'ssh' $SRCDIR root@${DESTHOST}:${DESTHOSTDIR} &>/dev/null && \
echo "At ${TIME} on ${DATE}, file $FILECHANGE was backed up via rsync" >> /var/log/filesync.log

done

 

需要注意的是,此脚本中的rsync是通过ssh加密后进行文件传输的,因此需要事先配置好相应的ssh能够基于密钥对用户进行认证,以免每一次文件同步都需要用户手动输入密码。

当然,如果数据传输不需要加密,此处也可以通过在目录主机的启动rsyncd守护进程来实现。

三、配置rsyncd+inotify实现文件实时同步:

本案例实现监控原主机上指定目录中的所有文件变化,并将变化实时同步至目标主机的指定目录中;所用主机及相关目录如下:
源主机:RHEL5.4(x86),172.16.100.1, 文件所在的目录为/www/htdocs;
目标主机:RHEL5.4(x86),172.16.100.6, 文件所在的目录为/www/htdocs;

1、设定目标主机(本例为172.16.100.6)

本案例中采用基于rsync守护进程的方式进行数据同步,其数据传输过程是明文方式,因此只适用于在特定的场景中应用。

1)安装相关软件:
目标主机是接收别的主机发送来的文件的服务器,因此,其rsync需要以守护进程的方式工作。rsync服务通常基于超级守护进程xinetd管理的方式来实现,因此需要事先安装rysnc和xinetd:
# yum -y install rsync xinetd

2)为rsync提供配置文件/etc/rsyncd.conf,内容类似如下内容:

# Section 1: Global settings
uid = nobody
gid = nobody
use chroot = no
max connections = 3
strict modes = yes
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log
# Section 2:Directory to be synced
[htdocs]
path = /www/htdocs
ignore errors = yes
read only = no
write only = no
hosts allow = 172.16.0.0/16
hosts deny = *
list = false
uid = root
gid = root
auth users = wwwuser
secrets file = /etc/rsync.passwd

 

其中的相关指令及其说明可以通过rsyncd.conf的手册而获取。而其访问控制功能也可基于xinetd进行,具体方法请参照xinetd.conf的手册页。

3)提供secrets file所指定的口令文件/etc/rsync.passwd,其内容类似如下:
htdocsuser:passwOrdForhtdOcs

其中冒号前的是用户名,冒号后的是对应用户的密码。此文件不能为其他任意用户可访问,因此可用如下命令修改:
# chmod 600 /etc/rsync.passwd

4)配置服务可以开机启动:

# chkconfig rsync on
# chkconfig xinetd on
# service xinetd start

#默认情况下,rsyncd监听的端口为873/TCP,这可以通过如下命令查看:
# netstat -tnlp | grep ":873"
tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 3653/xinetd

 

2、设定源主机

1)安装相关软件
源主机需要实时监控指定目录中的所有文件上与文件改变相关的事件,并在事件发生时将改变的数据同步至目录主机,因此,源主机上需要确保内核支持inotify,并安装inotify-tools和rsync。

rsync的安装参照目标主机的中的方式进行即可。

inotify-tools的安装可以基于源码编译的方式进行,也可以通过安装其rpm进行。
源码下载地址:http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
rpm包下载页面:http://rpm.pbone.net/index.php3/stat/4/idpl/15265939/dir/redhat_el_5/com/inotify-tools-3.14-1.el5.i386.rpm.html

这里以编译源代码的方式演示安装过程:

# tar xf inotify-tools-3.14.tar.gz
# cd inotify-tools-3.14
# ./configure
# make
# make install
# echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
# ldconfig

 

2)为源主机的rsync提供通过htdocsuser用户同步文件至目标主机的口令文件
# echo 'passwOrdForhtdOcs' > /etc/rsync.passwd
# chmod 600 /etc/rsync.passwd

注意,对于RHEL5.4自带的2.6.8版本的rsync来说,其客户端(即此处的源主机上的rsync)的口令文件中只能保存用户的口令,而不能类似目标主机上可同时指定用户名。

3)建立脚本/root/bin/htdocsync.sh,通过inotifywait监控目标文件上的相应事件,并在事件触发时启动同步过程:

#!/bin/bash
#
DESTHOST=172.16.100.6
DESTHOSTDIR=/www/htdocs/
SRCDIR=/www/htdocs/

inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' -e close_write,modify,delete,create,attrib $SRCDIR | while read DATE TIME DIR FILE; do

FILECHANGE=${DIR}${FILE}

rsync -avz --password-file=/etc/rsync.passwd $SRCDIR htdocsuser@${DESTHOST}::htdocs &>/dev/null && \
echo "At ${TIME} on ${DATE}, file $FILECHANGE was backed up via rsync" >> /var/log/websync.log
done

 

而后给此脚本执行权限,并执行即可:

# chmod u+x /root/bin/htdocsync.sh
# /root/bin/htdocsync.sh &

 

如果想让此功能可以在开机时自动启动,则可以通过如下方式进行:

# echo '/root/bin/htdocsync.sh &' >> /etc/rc.d/rc.local

 

PHP实现版本: https://www.cnblogs.com/zl0372/articles/Inotify_1.html

谋胆并重
目录
相关文章
|
1月前
|
Linux 数据安全/隐私保护 Windows
命令方式:window向linux传文件
【10月更文挑战第6天】本文介绍了如何在Linux系统中通过命令`ip a`获取IP地址,并在Windows系统下使用CMD命令行工具和SCP命令实现文件传输。示例展示了如何将D盘中的`mm.jar`文件上传至IP地址为192.168.163.122的Linux系统的/up/目录下,最后在Linux系统中确认文件传输结果。
238 65
|
26天前
|
运维 安全 Linux
Linux中传输文件文件夹的10个scp命令
【10月更文挑战第18天】本文详细介绍了10种利用scp命令在Linux系统中进行文件传输的方法,涵盖基础文件传输、使用密钥认证、复制整个目录、从远程主机复制文件、同时传输多个文件和目录、保持文件权限、跨多台远程主机传输、指定端口及显示传输进度等场景,旨在帮助用户在不同情况下高效安全地完成文件传输任务。
177 5
|
26天前
|
Linux Shell 数据库
Linux文件查找新姿势:总有一种你没见过
【10月更文挑战第18天】文件查找是Linux用户提升工作效率的重要技能。本文介绍了几种实用的文件查找方法,包括基础的`find`命令、快速的`locate`和`mlocate`、高效的`fd`工具、以及结合`grep`和`rg`进行内容搜索。此外,还提供了编写Shell脚本和使用图形界面工具的建议,帮助你更灵活地管理文件。
62 3
|
1月前
|
Linux Shell
Linux系统文件默认权限
Linux系统文件默认权限
|
8天前
|
Linux 开发工具 Perl
在Linux中,有一个文件,如何删除包含“www“字样的字符?
在Linux中,如果你想删除一个文件中包含特定字样(如“www”)的所有字符或行,你可以使用多种文本处理工具来实现。以下是一些常见的方法:
33 5
|
8天前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
26 6
|
8天前
|
Linux
在 Linux 系统中,`find` 命令是一个强大的文件查找工具
在 Linux 系统中,`find` 命令是一个强大的文件查找工具。本文详细介绍了 `find` 命令的基本语法、常用选项和具体应用示例,帮助用户快速掌握如何根据文件名、类型、大小、修改时间等条件查找文件,并展示了如何结合逻辑运算符、正则表达式和排除特定目录等高级用法。
35 6
|
9天前
|
监控 Linux Perl
Linux 命令小技巧:显示文件指定行的内容
在 Linux 系统中,处理文本文件是一项常见任务。本文介绍了如何使用 head、tail、sed 和 awk 等命令快速显示文件中的指定行内容,帮助你高效处理文本文件。通过实际应用场景和案例分析,展示了这些命令在代码审查、日志分析和文本处理中的具体用途。同时,还提供了注意事项和技巧,帮助你更好地掌握这些命令。
23 4
|
15天前
|
网络协议 Linux
linux系统重要文件目录
本文介绍了Linux系统中的重要目录及其历史背景,包括根目录、/usr、/etc、/var/log和/proc等目录的结构和功能。其中,/etc目录下包含了许多关键配置文件,如网卡配置、DNS解析、主机名设置等。文章还详细解释了各目录和文件的作用,帮助读者更好地理解和管理Linux系统。
39 2
|
14天前
|
缓存 监控 Linux