如何“查找”沒有被任何程序打開的文件
我有幾個 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 the
grep -v -E` 命令將該命令括起來。