“inotifywait -e close_write”忽略监视目录中的新文件夹

“inotifywait -e close_write”忽略监视目录中的新文件夹

我正在尝试复制保存到监视文件夹的已完成文件。我使用 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而不是CREATEwith 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) 的格式字符串。还有一个小的竞争条件,其中事件可以触发,但在处理循环和评估目标类型之前目标可能会被删除甚至替换。

相关内容