我正在编写一个脚本来监视文件夹中的任何文件创建、删除和更改。当其中一种情况发生时,用户会收到通知(每 30 秒一次)。
目前,我正在使用for
循环来遍历目录中的文件,并将它们与事先创建的文件数组进行比较,但我无法区分添加的新文件和已修改的文件。
我正在使用的代码如下。
start()
{
files=(~/Junk/*)
while true; do
loopstart=$(date +%s)
watcher
sleep 15
done
}
watcher()
{
ls -1 ~/Junk
echo -e "\n"
for f in ~/Junk/*; do
if [[ ! "${files[@]}" =~ "$f" ]]; then
echo -e "\n$f has been added"
else
last_modified=$(stat -c %Z "$f")
if [ $(($loopstart - $last_modified)) -le 15 ]; then
echo -e "\n$f has been changed"
fi
fi
done
for f in "${files[@]}"; do
if [ ! -e "$f" ]; then
echo -e "\n$f has been deleted"
fi
done
files=(~/Junk/*)
}
start_watcher
我知道 inotify 和其他系统可以提供解决方案;我只需要一个仅限 Bash 的解决方案。
答案1
您可以使用以下输出
find . -mindepth 1 -maxdepth 1 -type f -printf '%C@ %T@ ' -ls
stat
这比每个文件调用(尤其是多次)要快得多。-printf
和的组合-ls
可以更好地处理奇怪的文件名。如果您可以确定不会发生此类情况,那么您可以使用
-printf '%i %C@ %T@ %P'
反而。
索引节点(如注释中所述)标识对象。 ctime 和 mtime 告诉您文件数据或元数据是否已写入(但不会告诉您它是否确实已更改)。您应该将这些数据写入数组中
find ... | while IFS= read ctime mtime inode dummy1 ... dummy9 rest; do ...
环形。
答案2
问题出在剧本的最后。我将重新发布您的脚本并进行更正。
将“start_watcher”更改为“start”,因为您正在尝试运行启动功能。
答案3
尝试使用 Auditd
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/security_guide/chap-system_auditing
要监视目录,您需要
auditctl -w /path/to/dir -p wa -k CHANGED_ON_DIR