我正在尝试使用 inotifywait 来观看文件夹(/shares/Photos),当它检测到添加到文件夹中的 jpg 时,我需要将其调整为子目录($small_dir)。在照片目录下会有很多 jpg 的子文件夹。
树长这样
shares
-Photos
-Folder 1
-Folder 2
.
.
.
基本上每当有人将图片复制到folder 1
我需要创建一个新的子文件夹,然后调整图像大小并将较小的版本放入该文件夹中。
所以树会变成:
shares
-Photos
-Folder 1
-Resized
-Folder 2
.
.
.
到目前为止我的代码:
inotifywait -mr --timefmt '%m/%d/%y %H:%M' --format '%T %w %f' -e close_write /shares/Photos --includei "\.jpg|\.jpeg" |
while read -r date time dir file; do
changed_abs=${dir}${file}
small_dir=${dir}${target}/
printf "\nFile $changed_abs was changed or created\n dir=$dir \n file=$file \n small_dir=$small_dir \n"
# Check if the $small_directory exists, if not create it.
if [ -d "$small_dir" -a ! -h "$small_dir" ]
then
echo "$small_dir found, nothing to do."
else
echo "Creating $small_dir"
mkdir $small_dir
chmod 777 $small_dir
fi
# Check to see if the file is in $small_dir, if it is, do nothing.
if [ "$dir" = "$small_dir" ]; then
printf "\nFile is in the $small_dir folder, nothing to do\n"
else
printf "\nResizing file into the $small_dir folder\n"
# Code to resize the image goes here.
fi
done
它主要工作,但我的头撞墙的是,如果我Photos
在脚本运行时创建一个新的子文件夹,inotifywait 只是忽略它并且什么都不做。
我尝试替换close_write
为,create
但没有任何区别,我真的不确定从这里去哪里。
任何建议/帮助将不胜感激。
OP正在使用:
关于
--includei
告诉的文档(粗体强调我的):那不是:“显示事件”而是“处理事件”。实际上,这意味着只有名称包含
.jpg
or的目录的事件.jpeg
才会被处理。不会处理发生但与过滤器不匹配的目录创建事件,因此
inotifywait
不会调用inotify_add_watch(2)
此事件以及稍后在 this 中发生的任何事情。因此,在这个子目录中永远不会有事件被监视。我找不到使用
--includei
或其他类似选项来表达“仅针对这些正则表达式或任何目录处理事件”的方法。更新:建议一种解决方法
所以让它工作的方法似乎必须在命令之外进行过滤。
grep
如果不是 tty,GNU将缓冲它的输出,所以添加--line-buffered
.这将受到用户输入的影响(如文件名中的空格)。为了缓解这种情况,
/
需要在目录和文件名之间使用分隔符(在文件名中无效)。由于目录部分方便地包含尾随/
,因此只需删除格式字符串中的空格就足够了(以及进一步的变量处理和重用,如changed_abs
)。同时,我正在纠正过滤以字符串or结尾的文件名的意图,不包括这些字符串,并可能改进对内部有空格的目录的初始处理(的影响,但以后还有更多需要修复)。OP 应该真正用脚本中的引号保护所有相关变量(jpg
jpeg
changed_abs
small_dir
{ }
不替换引号)。代替:
和:
没有完全测试,但这就是想法。我什至不确定是否需要目录测试(它似乎从来没有发生过
close_write
事件),但它不会受到伤害。笔记
如果不清楚,则必须为检测到的每个目录创建事件执行一个操作 (
inotify_add_watch(2)
) ,必须尽快将一个新监视添加到该目录,因为它可能会丢失其中的后续事件(竞争条件)。它甚至记录在BUGS部分:inotifywait
inotifywait
较新版本的
inotifywait
,当至少在内核> = 5.9 上以 root (或足够特权)运行时,应该能够使用该fanotify(7)
工具,但我无法设法让我的版本inotifywait
使用它,尽管应该是在支持下编译并具有足够新的内核。在fanotify(7)
将要使用的系统上,结合该--filesystem
选项,假设这可以消除必须为每个较新目录执行操作的需要,并使 OP 的方法基于过滤--includei
工作。