Linux find找一天前檔案不如預期:mtime怎麼算整天

想找一天前改過的檔案,寫了find -mtime +1,結果前天的有列出,昨天晚上的卻沒有。先分清你說的「一天前」是超過二十四小時,還是日曆上的昨天。GNU find的mtime天數按二十四小時區間計算,再把不足一個區間的部分捨去;加號也不是直接把條件改成超過二十四小時。

本文只列出示範檔案,不刪除或搬移資料。先用幾個已知修改時間驗證範圍,再把條件接回你的任務,避免把一個看似熟悉的天數直接套進清理腳本。

mtime看資料修改,不是檔案建立日期

mtime表示檔案資料最後修改時間。它與存取時間、檔案狀態變更時間不同,也不等於通用的建立日期。查備份或匯入紀錄前,先確認你要追的是內容被改,還是資料最初產生;選錯時間種類,即使天數邊界算對仍會得到不符合需求的名單。

這篇採GNU find的整數天數範例。假設執行時刻為基準,距離修改時間二十五小時,完整經過的二十四小時區間是1;四十七小時也仍是1;四十九小時則是2。不是四捨五入成最接近的一天。

不帶加減號,找的是一整段區間

find /your/test-folder -type f -mtime 1 -print

這表示修改時間距今至少二十四小時、未滿四十八小時的普通檔案。不是剛好二十四小時整,也不是所有一日以前的檔案。路徑只是你自己的測試目錄佔位,執行時應換成明確授權查看的目錄;不要直接照抄未知路徑。

如果想找最近二十四小時的過去修改,整數案例可用-mtime 0或-mtime -1。若檔案時間被設到未來,結果需要另行判斷,不能把這個範圍當成所有時間戳都正常的保證。最小測試只使用確實在過去的修改時間。

+1比較的是捨去小數後的大於1

-mtime +1在這個整數案例中,要完整區間數大於1,所以至少要到四十八小時。它不是「超過一個二十四小時就符合」。二十五與四十七小時的區間數仍是1,都不會通過這個比較。

相反地,-mtime -1要求區間數小於1,會選到未滿二十四小時的過去修改。符號是針對計算後的區間數比較,而不是把n改成一個自然語言的「n天前」標籤。這個小差別是清理名單少一天或多一天的常見原因。

建立五個時間,實際看三份名單

在新建的隔離示範目錄,建立距今二十三、二十五、四十七、四十九與七十三小時的五個空檔。touch -d是GNU touch的日期指定方式,會改修改時間,這些檔案只能是測試資料。

mkdir /tmp/mtime-case
cd /tmp/mtime-case
for age in 23 25 47 49 73; do
  touch -d "$age hours ago" "age-$age.txt"
done
find . -type f -mtime 1 -print
find . -type f -mtime +1 -print
find . -type f -mtime -1 -print

隔離Ubuntu 24.04的GNU findutils 4.9.0、GNU coreutils 9.4實跑:mtime 1列age-25.txt與age-47.txt;mtime +1列age-49.txt與age-73.txt;mtime -1只列age-23.txt。這三份名單和完整區間計算相符,不需要等待真檔案累積幾天才能核對。

範例刻意避開正好二十四與四十八小時的瞬間,因為建立檔案與執行find之間仍會經過時間。它用兩側有餘裕的資料確認範圍,精確邊界則依手冊的捨去與比較規則理解。不要把命令花了幾秒才跑完,誤讀成邊界規則忽然改變。

示範的列出順序不是功能要求;find的遍歷順序不一定按檔名或時間排序。核對時比較檔名集合即可,如果報告需要固定順序再另做適合的排序。遇到任意檔名時,也要注意換行字元會讓普通文字列表的邊界不清楚。

日曆上的昨天,是另一個基準

若需求是「昨天從午夜到下一個午夜改過」,不能直接拿距今二十四到四十八小時當成昨天。今天下午執行時,滾動區間與昨天的日曆範圍就不同。GNU find有-daystart選項,會讓後續受影響的時間測試按今天開始處理。

find /your/test-folder -daystart -type f -mtime 1 -print

這是官方文件給出的昨天範例;-daystart要放在受影響的時間測試前面。本文五個檔案的真實跑比較沒有使用這個選項,不把兩種基準合成同一份結果。放回網站任務時,還應核對執行環境的時區,避免把服務紀錄的日期和shell本地日期混在一起。

有些日期任務還會碰到日光節約時間或不同來源的時間戳。你應先決定按哪個時區的日曆日處理,再選合適的查詢方式。固定二十四小時的區間與所有日曆日期不一定是同一件事,不要只靠「一天」兩個字就省略基準。

先列出,別把條件立刻接刪除

如果原本想清掉舊暫存檔,先只用-print查看名單,確認路徑、檔案種類和時間範圍。這個指令的示範不需要-delete,也不需要把輸出交給rm。先得到符合預期的集合,才有條件按真正的清理授權處理下一步。

-type f讓本例限定普通檔案,避免目錄也混在名單中。但它不是對所有檔案都可刪的判定,來源可能仍在被程式使用,或者屬於其他服務。時間足夠舊只是一個篩選條件,還要結合資料用途和保留規則。

對固定備份目錄,可以先挑幾個已知時間的檔案比對,不要從整個檔案系統開始掃。找到的結果若太多,先縮小路徑與條件,確認哪些是預期資料。若結果為空,也不必立即把天數往下改,先核對基準和每個候選檔案的實際修改時間。

把條件寫成讀得懂的約定

在腳本註解裡,可以寫「距執行時至少四十八小時」或「依本地日曆的昨天」,比只寫「一天前」明確。之後有人把+1改成1,就能看出這是改範圍,而不只是修正一個數字。保留五檔最小案例,也方便在換系統後重新驗證。

本文引用GNU findutils發行包手冊與上游manpage,以及POSIX的find、touch規範。GNU擴充像-daystart與touch -d不應被假定所有POSIX實作都支援。若你在不同發行版或BSD系統使用,先查看實際版本與相應手冊,別只看命令名稱相同。

mtime條件判斷的是查詢時的檔案時間;遍歷期間資料仍可能改變。這份列出結果不是永久快照,也沒有凍結任何目錄。如果任務需要一致性快照或保證檔案不再被使用,需要另用符合服務需求的流程,不能從一次find名單推論已具備那些條件。

每次調整天數,都先重新核對預期名單。

參考資料

原文鏈接:https://wntheme.com/linux-find-mtime-day-boundary/,轉載請註明出處。
0

評論0

顯示驗證碼
沒有帳號?註冊  忘記密碼?