Inotifywait 不等待文件操作完成

问题描述 投票:0回答:1

我通过 Lutris 安装了《魔兽争霸 3》,从 /Download/ 复制自定义地图很麻烦,所以我写了一个脚本来帮我做到这一点。

问题是

inotifywait
应该等到下载(我不确定它在技术上是移动、创建还是写入)完成,然后将文件处理到脚本的其余部分,但事实并非如此。当我单击“下载”时,会创建一个 0 字节文件,脚本会立即拾取并复制该文件,然后高兴地宣布它成功了。

除了睡眠之外,如何让它等待文件写入/下载/移动完成?我对睡眠犹豫不决,因为我不知道即将到来的文件的文件大小和下载速度。

我确实找到了关于我的问题的这篇文章: bash 脚本 inotifywait 等待文件完全写入后再继续 它不能解决我的问题,因为 close_write 不会阻止它将空文件移交给要复制的脚本的其余部分。它要么不等待文件关闭进行写入,要么下载不写入。

我写了以下脚本:

#!/bin/bash

#This script runs at startup and watches \~/Downloads. When it finds a \*.w3x file, it checks  ./Games/battlenet/drive_c/users/user/Documents/Warcraft III/Maps/Download/ and if the file isn't there, it copies it there and then deletes the original from \~/Downloads


#Directory to be watched

DIR_TO_WATCH="$HOME/Downloads/"

#Directory to copy the files to

DEST_DIR="$HOME/Games/battlenet/drive_c/users/user/Documents/Warcraft III/Maps/Download/"

#Run inofifywait and wait for a CLOSE event which occures when a file was open for writing (e.g.: modifying, being copied, being downloaded, etc) and then the scrpit will check if the change fits this it's conditions. Whatever the outcome is, it will get pushed to the processing below with the '|' symbol

inotifywait -m "$DIR_TO_WATCH" -e close |

#Processing events. Every line of events if there are multiple

        while read path action file
        do
    
    
        #Check if there is a Warcraft 3 map
                if [[ "$file" == *.w3x ]];
                then
    
    
                #Check if the file already exists in the WC3 Download folder specified in DEST_DIR
                        if [ ! -f "$DEST_DIR/$file" ];
                        then
                                echo "NEW TRANSACTION ---$(date)---" >> wc3_mapsync.log
                                echo "$(date) | $file size before copy: $(stat -c%s "$path$file")" >> wc3_mapsync.log
                                cp "$path$file" "$DEST_DIR"
                                        if [ $? -eq 0 ]
                                        then    echo "$(date) | $file COPIED SUCCESSFULLY $path$file >>> $DEST_DIR" >> wc3_mapsync.log
                                                echo "$(date) | $file size after copy: $(stat -c%s "$DEST_DIR/$file")" >> wc3_mapsync.log
                                                echo "---END TRANSACTION---" >> wc3_mapsync.log
                                                rm "$path$file"
                                        else    echo "$(date) | $file COPY FAILED with exit status code $? '|' $path$file" >> wc3_mapsync.log
                                                echo "---END TRANSACTION---" >> wc3_mapsync.log
                                        fi
                        else
                                echo "$(date) | $file ALREADY EXITSTS, copy would be duplicate."  >> wc3_mapsync.log
                                echo "---END TRANSACTION---" >> wc3_mapsync.log
                        fi
                else :
                fi
        done
bash inotify inotifywait
1个回答
0
投票

根据我收到的评论,我修复了它,具体方法如下:

我采纳了 Charles Duffy 的建议并进行了修改。您是对的,下载是在脚本的输出所确认的部分进行的。我扔掉了我的注释,修剪了代码,并将 sleep 放置到了正确的位置,我认为它在关闭写入后读取文件名,等待(所以如果写入发生在下载等部分,它可以继续,重置周期),然后执行第二部分:

#!/bin/bash

#要观看的目录 DIR_TO_WATCH="$HOME/下载/"

#将文件复制到的目录 DEST_DIR="$HOME/Games/battlenet/drive_c/users/hori/Documents/Warcraft III/Maps/Download/"

inotifywait -m“$DIR_TO_WATCH”-e close_write |

    while read path action file
    do
        sleep 2

            if [[ "$file" == *.w3x ]];
            then

                    if [ ! -f "$DEST_DIR/$file" ];
                    then
                            cp "$path$file" "$DEST_DIR"
                    fi
            fi
    done

P.s.:我不知道为什么编辑器不将 #!/bin/bash 视为代码的开头

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.