帶有 curlsftpsf 掛載點的 inotifywait 未按預期移動文件
我正在使用 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
時,該文件沒有任何反應。
不幸的是,
inotify
API 不能用於監控遠端文件系統。Inotify 僅報告使用者空間程序通過文件系統 API 觸發的事件。因此,它不會擷取網路文件系統上發生的遠端事件。(應用程序必須退回到輪詢文件系統以擷取此類事件。)
相關問題:
也就是說,您問題中的腳本無論如何都不會按預期工作。
"%w%f"
使用 ’s 輸出格式的想法inotifywait
是為循環中的命令提供觸發已偵聽文件系統事件的文件的完整路徑。%w
擴展為監視文件的路徑($dir
目錄),並%f
擴展為導致事件的文件的(基本)名稱。因此,
inotifywait
它只為它擷取的每個事件發出一個完整的路徑。另一方面,read
為您的命令提供了三個要填寫的變數path
:action
和file
。預設情況下,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
從文件名末尾修剪空白字元(以處理名稱以空格或製表符結尾的不太可能的情況)。請注意,對於名稱包含換行符的文件,這仍然會失敗。