Mv

帶有 curlsftpsf 掛載點的 inotifywait 未按預期移動文件

  • July 31, 2020

我正在使用 Ubuntu 20.04。我正在嘗試為inotifywait. 這個想法是在每次目錄發生變化時將文件從 移動dir到;target此腳本是一個 shell 文件,可以通過命令行自動或手動啟動。

#!/usr/bin/env bash
dir=/mnt/test1/test/ #ftp point of mount
target=/var/www/html/local/ #normal directory on filesystem

inotifywait -m "$dir" --format "%w%f" -e create -e moved_to |
   while read path action file; do
      mv "$file" "$target"
   done

並且要移動的文件需要具有*.txt格式。inotify 正在觀看,但是當我使用我的 ftp 客戶端將文件放入dir並等待 inotify 將其移動到target時,該文件沒有任何反應。

我用這個作為參考:https ://unix.stackexchange.com/a/86292/425161

不幸的是,inotifyAPI 不能用於監控遠端文件系統。

來自man 7 inotify

Inotify 僅報告使用者空間程序通過文件系統 API 觸發的事件。因此,它不會擷取網路文件系統上發生的遠端事件。(應用程序必須退回到輪詢文件系統以擷取此類事件。)

相關問題:

也就是說,您問題中的腳本無論如何都不會按預期工作。

"%w%f"使用 ’s 輸出格式的想法inotifywait是為循環中的命令提供觸發已偵聽文件系統事件的文件的完整路徑。%w擴展為監視文件的路徑($dir目錄),並%f擴展為導致事件的文件的(基本)名稱。

因此,inotifywait它只為它擷取的每個事件發出一個完整的路徑。另一方面,read為您的命令提供了三個要填寫的變數pathactionfile。預設情況下,read根據 in 中的字元拆分讀取行IFS並將生成的標記分配給作為參數給出的名稱:第一個標記給第一個名字,第二個標記給第二個名字,等等。(並且,如果有倒數第二個名字後面的標記比名字多,所有剩餘的標記都分配給姓氏)。

正如您可以輕鬆檢查的那樣,在您的程式碼中,觸發監視事件的任何文件的完整路徑都分配給path(除非它包含空白字元):

$ inotifywait -m --format "%w%f" -e create -e moved_to /tmp/test |
 while read path action file; do
   printf 'path: "%s"; action: "%s"; file: "%s"\n' "$path" "$action" "$file"
 done
# Type "touch /tmp/test/foo" in a different terminal
path: "/tmp/test/foo"; action: ""; file: ""

此外,正如您在 Q/A 中的不同答案中指出的那樣,您應該監聽close_write事件,而不是監聽create. 您可能正在尋找的是:

inotifywait -m -q --format "%w%f" -e close_write -e moved_to -- "$dir" |
 while IFS= read -r src; do
   if [ "${src##*.}" = 'txt' ]; then
     mv -- "$src" "$target"
   fi
 done

-r告訴read不要解釋反斜杠轉義的序列。IFS=用於防止read從文件名末尾修剪空白字元(以處理名稱以空格或製表符結尾的不太可能的情況)。

請注意,對於名稱包含換行符的文件,這仍然會失敗。

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