Shell-Script

如何使用 inotifywait 監視目錄以創建特定副檔名的文件

  • March 20, 2022

我看過這個答案

您應該考慮使用 inotifywait,例如:

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        echo "The file '$file' appeared in directory '$path' via '$action'"
        # do something with the file
    done

我的問題是,上面的腳本監視一個目錄以創建任何類型的文件,但是我如何修改inotifywait命令以僅在創建某種類型/副檔名的文件(或移動到目錄中)時報告 - 例如它應該創建任何.xml文件時報告。

我嘗試了什麼:

我已經執行了inotifywait --help命令,並閱讀了命令行選項。它具有排除--exclude <pattern>某些類型的文件的--excludei <pattern>命令(通過使用正則表達式),但我需要一種方法來包含某種類型/副檔名的文件。

如何修改 inotifywait 命令以僅在創建特定類型/副檔名的文件時報告

請注意,這是未經測試的程式碼,因為我現在無權訪問inotify。但是類似的東西應該​​可以工作:

inotifywait -m /path -e create -e moved_to |
   while read directory action file; do
       if [[ "$file" =~ .*xml$ ]]; then # Does the file end with .xml?
           echo "xml file" # If so, do your thing here!
       fi
   done

雖然前一個答案的雙重否定方法是一個好主意,因為(正如 TMG 指出的那樣)它確實將過濾工作轉移到inotifywait,但它是不正確的。

例如,如果一個文件以 then 結尾,as則它不會匹配[^j][^s]$,因為最後一個字母s不匹配[^s],因此它不會被排除。

在布爾術語中,ifS是語句:

“最後一個字母是s

並且J是聲明:

“倒數第二個字母是j

那麼--exclude參數的值在語義上應該等於not(J and S),根據德摩根定律not(J) or not(S)

另一個潛在的問題是 in zsh,$path是一個內置變數,表示等效於 的數組$PATH,因此該while read path ...行將完全混亂$PATH並導致所有內容都無法從 shell 執行。

因此正確的做法是:

inotifywait -m --exclude "[^j].$|[^s]$" /path -e create -e moved_to |
   while read dir action file; do
       echo "The file '$file' appeared in directory '$dir' via '$action'"
   done

注意.which 需要[^j]確保匹配應用於倒數第二個位置,並且|字元(表示上面提到的布爾 OR)不應在此處轉義,因為--exclude它採用 POSIX 擴展正則表達式。

但是,請查看支持@ericcurtin 的答案,對於較新版本的答案,這inotifywait是一種更清潔的方法。

引用自:https://unix.stackexchange.com/questions/323901