我有几个 cron 任务,每个任务都会留下一个单独的日志文件。成功的任务不会产生任何输出,所以我得到了很多空日志。
我想每天自动清理它。请求find
查找 size=0 很容易,但是我想确保我不会删除刚刚由正在运行的任务创建但尚未关闭的日志。
有没有办法告诉find
跳过打开的文件,或者我需要诉诸lsof
?
答案1
据我所知,没有直接的方法可以通过 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` 命令将该命令括起来。