我正在尝试复制保存到监视文件夹的已完成文件。我使用 inotifywait 创建了一个 bash 脚本来监视该文件夹。
我的原始脚本非常适合文件和文件夹/子文件夹。一旦我用“-e close_write”替换“-e create -e moving_to”,它就不再识别/处理保存在监视文件夹中的文件夹。它现在仅适用于文件。我需要对此进行更改的原因是因为我的很多文件都很大(并且文件夹中存在多个文件)并且需要一些时间才能完全保存(到监视文件夹)并且脚本在文件被保存之前会运行所有进程。完全保存/复制。
我也尝试过“等待”命令,但它什么也没做。我知道有更复杂/更好/正确的使用方法,但我还没有弄清楚。在 inotify 中找到“close_write”事件后,我觉得它会等待当前进程/命令完成后再开始下一个进程/命令,从而完全满足我的需要。它可以完美地处理大型单个文件,但每当将文件夹复制到监视文件夹时,它就会 MIA(不执行任何操作)。
这是我的脚本示例。我不太擅长编写 bash 脚本,如果写得一团糟,我很抱歉。
#!/bin/bash
WATCHED=/mnt/Watched
DESTINATION=/mnt/Destination
user=userid
group=groupid
perms=777
# Step 1 - Copying completed files to Destination folder
inotifywait -m -e close_write --format %f $WATCHED \
| while read new
do
echo Detected new file $new, Copying to Destination folder
cp -r "$WATCHED/$new" "$DESTINATION/"
wait
# Step 2 - Deleting unwanted files from Destination folder
echo Deleting unwanted files from Destination folder
find $DESTINATION -type f -iname "*.txt" -delete
find $DESTINATION -type f -iname "*.nfo" -delete
find $DESTINATION -type f -iname "*.website" -delete
find $DESTINATION -type f -iname "*.exe" -delete
find $DESTINATION -type f -iname "*.html" -delete
find $DESTINATION -type f -iname "*.htm" -delete
find $DESTINATION -type f -iname "*.sfv" -delete
find $DESTINATION -type f -iname "*.parts" -delete
find $DESTINATION -type f -iname "*.jpg" -delete
find $DESTINATION -type f -iname "*.png" -delete
find $DESTINATION -type f -iname "*.doc" -delete
sleep 10
# Step 3 - Change permissions of new files in Destination folder
echo Changing ownership and permissions to Destination folder and files
chown -R $user:$group "$DESTINATION"
chmod -R $perms "$DESTINATION"
done
任何指导将不胜感激。
谢谢
编辑...
我一生都无法让这个脚本看到添加到监视文件夹中的新文件夹。它实际上什么也没做。如果我用close_write
&create
替换moved_to
并且不进行其他更改,它会正确看到文件夹和内容并进行处理。我觉得这很奇怪。
事实上,我什至尝试制作一个小测试脚本,看看是否可以让它与 if/elif/else 语句一起使用,但是当我在监视文件夹中复制文件夹时,脚本再次执行任何操作(甚至不执行任何操作)到循环)。如果我放入一个文件,那么它会提供正确的输出。
这是我运行的测试脚本。有人能确认他们是否可以正确识别和处理新文件夹吗?
#!/bin/bash
WATCHED=/mnt/Watched
inotifywait -re close_write --format '%w%f' -m $STEP1_WATCHED \
| while read -r new
do
if [[ -d "$new" ]]; then
echo "Detected new folder $new"
elif [[ -f "$new" ]]; then
echo "Detected new file $new"
else
echo "neither $new"
fi
done
done
答案1
您没有看到从脚本创建的目录的原因是您正在寻找CLOSE_WRITE
而不是CREATE
with IS_DIR
:
inotifywait . # Terminal 1
Setting up watches.
Watches established.
./ CREATE,ISDIR zz
mkdir zz # Terminal 2
现在,因为CREATE
也可以应用于您需要测试项目类型作为决策一部分的文件:
#!/bin/bash
watchDir=/mnt/watched
inotifywait -qre CLOSE_WRITE,CREATE --format $'%e\t%w%f' --monitor "$watchDir" |
while IFS=$'\t' read -r events item
do
if [[ -d "$item" ]]
then
echo "New directory '$item'"
elif [[ "$events" =~ CLOSE_WRITE ]]
then
if [[ -f "$item" ]]
then
echo "New file '$item'"
elif [[ -e "$item" ]]
then
echo "New unknown item '$item'"
fi
fi
done
对于包含换行符 ( touch $'break\nfile'
) 或以一个或多个制表符 ( touch $'\ttabbed'
) 开头的文件或目录名,此代码将失败,因为inotifywait
无法使用包含空字符 ( \000
) 的格式字符串。还有一个小的竞争条件,其中事件可以触发,但在处理循环和评估目标类型之前目标可能会被删除甚至替换。