请编写一个 Shell 脚本,用于监控指定文件的变化,并在文件被修改、删除或创建时输出相应提示。需要考虑轮询机制和常用监控工具的使用。
考察说明
考查 Shell 脚本编写能力,特别是文件监控的实现方式和常见工具的使用。
回答思路
- 【回答框架 1】文件监控有两种常见实现方式:轮询和实时通知。轮询通过循环调用 stat 或 md5sum 定期检查文件状态,比如用 sleep 指定间隔,对比文件大小、修改时间或哈希值。实时通知依赖 inotify 等内核机制,Shell 中常用 inotifywait 工具。
- 【回答框架 2】轮询实现简单:编写 while 循环,每次获取文件的当前状态(如 mtime 和大小),与上次记录对比,若不同则输出变化提示并更新记录,然后 sleep 几秒继续循环。但轮询有延迟且消耗资源,适合监控频率不高的场景。
- 【回答框架 3】inotifywait 是更高效的方案,它基于 inotify 机制,可以监控文件或目录的多种事件,如 modify、create、delete、move 等。使用格式如 inotifywait -m -e modify,create,delete file 或目录,-m 表示持续监控,-e 指定事件。脚本中通常将 inotifywait 输出通过 while read 读取,对每一行事件做出响应。
- 【回答框架 4】实现时要注意工具依赖:inotifywait 属于 inotify-tools,可能未预装,需要用包管理器安装;而轮询只依赖核心命令,兼容性更好。另外,监控目录和监控文件在事件处理上略有不同,例如目录要处理进入子目录的事件,需要配合 -r 参数。
- 【回答框架 5】健壮性要点:监控脚本通常需要记录状态文件或 PID 以便停止;处理被监控文件不存在或权限不足的情况;避免 sleep 与轮询间隔过短导致频繁检查,同时也要兼顾实时性需求。对于关键文件的监控,建议结合日志记录和告警通知。
- 【关键点 1】轮询实现利用 stat 或 md5sum 对比文件状态,简单但延迟高。
- 【关键点 2】inotifywait 基于内核事件,实时高效,但需要安装工具。
- 【关键点 3】监控目录时考虑递归监控和事件类型过滤。
- 【关键点 4】脚本注意处理文件权限和存在性检查,避免报错。
- 【关键点 5】实际应用常结合日志和告警,监控不仅仅是输出提示。
- 【易错点 1】在权限不足或文件不存在时,stat 和 inotifywait 可能出错,要捕获异常并处理。
- 【易错点 2】轮询间隔过短会消耗 CPU,间隔过长会漏掉快速变化,需要平衡。
- 【易错点 3】inotifywait -m 会持续输出,需正确读取管道,避免阻塞。