Logging

如何“查找”沒有被任何程序打開的文件

  • November 20, 2019

我有幾個 cron 任務,每個任務都留下一個單獨的日誌文件。成功的任務不會產生任何輸出,所以我得到了很多空日誌。

我想每天自動清理它。請求find查找 size=0 很容易,但是我想確保我沒有刪除剛剛由正在執行的任務創建但尚未關閉的日誌。

有沒有辦法告訴find跳過打開的文件,或者我需要求助於lsof

據我所知,find 沒有直接的方法。

解決方案一

生成目標文件夾中打開文件的列表lsof.lst。並生成該文件夾的查找列表。然後顯示find.lst不在lsof.lst列表中的文件。

要生成 lsof.lst,請使用以下命令:

lsof +D folderName | awk '{ if(NR>1)print $9 }' | sort | uniq > lsof.lst

然後使用以下命令顯示目前未在同一文件夾中打開的文件:

find folderName | grep -v -f lsof.ls

解決方案二

您也可以像這樣一次性完成:

find folderName | grep -v -E `lsof +D folderName | awk '{ if(NR>1)print $9 }' | sort | uniq | awk '{print $0}' ORS='|' | sed 's/.$//'`

解釋

現在我將嘗試解釋該命令,以便您將來可以改進或更改它或使用幾個命令行工具。

find folderName將生成該文件夾和子文件夾中所有文件的列表。find 命令的輸出通過管道傳輸到grep此處與-v開關一起使用的地方,以從 find 命令的管道輸出中排除參數中提到的項目-E。結果將是減去參數find中提到的項目的輸出。-E

這裡的訣竅是生成打開文件的列表,並將其放入grep -v -E期望並可以使用的格式。grep -E 獲取由“|”分隔的字元串列表。

lsof +D FolderName將生成該文件夾中打開文件的列表,但該列表包括一個標題和許多列,其中之一是文件名,它可能包含重複項。所以我們習慣awk '{ if(NR>1)print $9 }'做兩件事,刪除第一行if(NR>1)並只列印包含文件名的列print $9。結果是該文件夾中打開文件的文件名列表,沒有標題。

要刪除重複項,將輸出通過管道傳送到sort然後uniq,下一個命令awk '{print $0}' ORS='|'將列表變成一個由“|”分隔的句子,最後一個命令刪除最後一個“|” 因為它是多餘的。

用反引號’ ' executes that command in that spot and feeds the output to thegrep -v -E` 命令將該命令括起來。

引用自:https://serverfault.com/questions/992616