我想创建一个脚本,记录一天内对某个目录或该目录中任何文件的每次访问,为此,我使用了 inotifywait,但我不喜欢输出,即使我格式化了它,我也需要访问/修改该文件的用户。我想以表格格式打印它。像这样:
TIME USER FILE EVENT
%mm:%HH PM/am root /home/root/x Accesed(or anything the inotifywait gives)
我尝试了这样的事情:
#!/bin/sh
watchedDir=$1
logFileName="$(date +'%d.%m.%Y').log"
iwait() {
inotifywait -r -m --timefmt "%Y/%m/%d %H:%M:%S" --format "%T;%w%f;%e" $watchedDir >> "$PWD/.$logFileName.tmp"
}
write_to_file() {
while true; do
last_entry=$(tail -n 1 "$PWD/$logFileName.tmp")
time=$(tail -n 1 "$PWD/$logFileName.tmp" | cut -f1 -d';')
user=$(stat $last_entry --format="%U")
file=$(tail -n 1 "$PWD/$logFileName.tmp" | cut -f2 -d';')
event=$(tail -n 1 "$PWD/$logFileName.tmp" | cut -f3 -d';')
awk -v time="$time" -v user="$user" -v file="$file" -v event="$event" 'BEGIN {printf("%s %8s %8s %8s \n" ,"Time", "User", "File", "Event")}
{printf("%s %s %s %s\n", time, user, file, event)}' >> "$PWD/.$logFileName.tmp"
done
}
if [ "$(realpath $watchedDir)" != "$PWD" ]
then
iwait &
write_to_file &
wait
fi
我还发现,如果我尝试监视当前目录并将文件重定向到当前目录,它将淹没输出……所以我尝试使用它来克服它if
。
我怎样才能做这样的事?
答案1
替代解决方案iwatch
iwatch -c "./log.sh %f %e" ./test_iwatch/
log.sh
#!/bin/sh
d=$(date -u --rfc-3339='seconds')
u=$(stat -c '%U' "$1")
printf "%s %8s %8s %8s\n" "$d" "$u" "$1" "$2" >> log.log
结果日志示例:
2020-11-13 21:48:41+00:00 user ./test_iwatch//29 IN_MOVED_TO
2020-11-13 21:49:11+00:00 user ./test_iwatch//220 IN_CREATE
2020-11-13 21:49:11+00:00 user ./test_iwatch//220 IN_CLOSE_WRITE
2020-11-13 21:51:51+00:00 ./test_iwatch//20 IN_ISDIR,IN_MOVED_FROM
2020-11-13 21:51:51+00:00 user ./test_iwatch//30 IN_ISDIR,IN_MOVED_TO
为了更好地控制制表,请尝试以下操作
printf "%s\t%-16s\t%-24.24s\t%-16s\n"
输出将会像这样:
2020-11-13 22:21:38+00:00 user ./test_iwatch//blue IN_CREATE
2020-11-13 22:21:38+00:00 user ./test_iwatch//blue IN_CLOSE_WRITE
2020-11-13 22:21:44+00:00 ./test_iwatch//blue IN_MOVED_FROM
2020-11-13 22:21:44+00:00 user ./test_iwatch//red IN_MOVED_TO
格式“-%X.Yf”:
-
左对齐X
最小宽度(焊盘)Y
最大宽度(修剪)\t
&\n
转义字符 TAB & NEWLINE