Cron

刪除所有超過 7 天的文件的 Cron 作業:-exec rm -f {} ;vs-刪除

  • January 8, 2022

我想執行一個刪除.txt超過 7 天的文件的 cron 作業。我有兩個命令。第一個命令:

/usr/bin/find /var/www/example.com/wp-content/targetdir -name "*.txt" -type f -mtime +7 -exec rm -f {} \;

第二條命令:

/usr/bin/find /var/www/example.com/wp-content/targetdir -name "*.txt" -type f -mtime +7 -delete

這兩個命令都可以用來刪除.txt超過 7 天的文件。我讀過第一個命令與race condition. 能否詳細說明使用第二個命令相對於第一個命令的優勢?使用其中一個的優點和缺點是什麼?

我看到的比賽是這樣的,從Stéphane Chazelas 的評論到另一個問題:

請注意,-exec rm {} +有競爭條件漏洞-delete(如果可用)沒有。所以不要在其他人可寫的目錄上使用它。一些發現還具有-execdir減輕這些漏洞的作用。

我實際上並沒有在(*)那裡看到詳細說明,但是我在那裡看到的比賽與如何將完整路徑傳遞給文件有關,從而導致在該過程中-exec rm再次遍歷樹。rm

find遍歷樹並評估它在命令行上給出的條件之後,rm再次遍歷樹,它不知道給定的條件find,所以現在它們沒有被檢查。使用-deleteand -execdirfind遍歷樹,進行任何檢查,然後刪除文件,始終保持目錄上的文件描述符打開。

find有人可能會介入並在評估其條件和rm執行之間重命名文件或目錄。所以,像這樣:

  1. 根執行find . -type f -user joe -exec rm -f {} \;
  2. find執行並找到目錄./this/,其中包含使用者擁有的一些文件joe
  3. 另一個使用者重命名./this並創建一個具有相同名稱的符號連結,指向其他地方
  4. find執行rm -f ./this/hello.txt,現在跟隨符號連結。

hello.txt現在可以由任何人擁有,而不僅僅是 user joe,並且因為find是作為 啟動的rootrm所以它也很高興地刪除了符號連結另一端的文件。這是一個經典的使用時間檢查 (TOCTTOU) 漏洞

人們可能會提出更糟糕的例子,但這是一個普遍的想法。

使用-deleteor ,這不會發生,因為打開-execdir的文件描述符仍然指向同一個目錄,即使該目錄被重命名。將其工作目錄設置為該目錄執行(有系統呼叫通過文件描述符更改工作目錄,同樣不通過名稱查找),同時同樣刪除使用相對於包含目錄的名稱(使用)。find``./this``-execdir``rm``fchdir()``-delete``unlinkat()

請注意,預設情況下(即沒有-L選項),find在遍歷目錄樹時不遵循找到的符號連結。這在這裡沒有幫助,因為再次rm只是將它提供給底層系統呼叫的路徑傳遞給了底層系統呼叫,並且像往常一樣遵循符號連結。這確實意味著被替換的目錄(./this上面)必須是一個被符號連結(或另一個目錄)替換的實際目錄,而不是被另一個符號連結替換的符號連結。

(*)寫完這篇文章 20 分鐘後,我注意到 Stéphane 的回答(連結如下)確實有一個指向描述相同種族問題的 GNU 手冊的連結。(嘆。)


-delete暗示-depth和無效的問題與此-prune無關,而不是競爭條件。為什麼 find with -delete 刪除了我的/save/ 目錄中的文件,而 find without delete 無法找到它們?GNU coreutilsfind似乎已經收到了一條錯誤消息:

$ find a -name foo -prune -o -name hello.txt -delete
find: The -delete action automatically turns on -depth, but -prune does nothing when -depth is in effect.  If you want to carry on anyway, just explicitly use the -depth option.

另一個區別是-exec rm -f -- {} +僅使用標準工具,而-delete不是標準工具,即使有些普遍支持。例如 FreeBSD 和 GNU 支持它,但 Busybox 不支持。請參閱:查找:“-exec rm {};” 與“-delete”相比——為什麼前者被廣泛推薦?在 superuser.com 上。

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