我正在监视文件夹($WATCHED)中的新文件(仅 .mkv)/文件夹。当出现某些内容时,请将它们复制到目标文件夹 ($DESTINATION),然后更改所有权和权限。
这是我正在使用的脚本。
#!/bin/bash
WATCHED=/mnt/Watched
DESTINATION=/mnt/Destination
user=usrid
group=grpid
perms=755
inotifywait -re CLOSE_WRITE,CREATE,MOVED_TO --format $'%e\t%w%f' -m $WATCHED |
while IFS=$'\t' read -r events new
do
# Detecting and copying new files/folders
sleep 5
if [[ -d "$new" ]]
then
echo "Folder Detected: $new, Copying to Destination folder"
cp -r "$new" "$DESTINATION/"
elif [[ "$events" =~ CLOSE_WRITE ]]
then
if [ -f "$new" ] && [ "${new##*.}" == mkv ]
then
echo "File Detected: $new, Copying to Destination folder"
cp -r "$new" "$DESTINATION/"
elif [[ -e "$new" ]]
then
echo "New unknown item '$new'"
fi
fi
echo "Changing ownership and permissions for $DESTINATION"
chown -R $user:$group "$DESTINATION"
chmod -R $perms "$DESTINATION"
echo
done
我对这个脚本有几个问题。
- 当文件夹中只有一个文件夹和一个文件时,由于某种原因,更改所有权/权限会运行 3 次。您可以从下面的输出中看到,第二个实例是单独的。不知道为什么?我知道我对此的定位和行动对于我想要实现的目标来说是不正确的。我希望在复制每个新的单独文件/文件夹时完成所有权/权限,而不是整个目标文件夹。我不确定仅更改每个新文件/文件夹的所有权/权限的正确方法。任何指导都将非常感激。
- 此脚本使用正确/相同的目录树将文件夹和文件复制到目录,但它也将文件复制到目标文件夹。所以我有该文件的两份副本。首先,为什么它直接在目标文件夹中进行复制,其次,如何阻止它这样做?
这是输出。
Folder Detected: /mnt/Watched/NewFolder, Copying to the Destination folder
Changing ownership and permissions for /mnt/Destination
Changing ownership and permissions for /mnt/Destination
File Detected: /mnt/Watched/NewFolder/NewFile.mkv, Copying to Destination folder
Changing ownership and permissions for /mnt/Destination
这就是我希望输出的样子
Folder Detected: /mnt/Watched/NewFolder, Copying to the Destination folder
Changing ownership and permissions for /mnt/Destination/NewFolder
File Detected: /mnt/Watched/NewFolder/NewFile.mkv, Copying to Destination folder
Changing ownership and permissions for /mnt/Destination/NewFolder/NewFile.mkv
谢谢
答案1
您正在寻找CREATE
和CLOSE_WRITE
事件,但没有在代码中将它们分开。
当一个新文件出现时,它很可能会生成这两个事件,首先在最初创建文件时生成“CREATE”事件,然后在实际写入后关闭文件时生成“CLOSE_WRITE”事件。
文件上的“CREATE”事件不会捕获 if 语句的任何分支,而只会运行“更改所有权和权限...”部分。
您需要决定要对每个事件执行什么操作,可能分别针对文件和目录。文件的“CREATE”事件可能不是很有趣,因为只有在创建文件而未打开文件进行写入时,才会在没有“CLOSE_WRITE”的情况下发生这种情况。 (如果有人open(filename, O_CREAT|O_RDONLY)
故意打电话,但touch
没有这样做,就会发生这种情况。)
我建议您添加一行来打印收到的事件,这样您就可以看到代码实际获取的内容,例如:
while IFS=$'\t' read -r events new
do
echo "get event: $events on file $new"
我也完全不确定你为什么要sleep 5
在循环中调用;除了延迟脚本之外,它似乎没有做任何事情。