查找所有进程打开的文件中最大的文件。
lsof
已经有打开的文件及其大小。它可能会传递正确的参数lsof
并处理输出。
答案1
一种复杂的方式如下所示:
lsof \
| grep REG \
| grep -v "stat: No such file or directory" \
| grep -v DEL \
| awk '{if ($NF=="(deleted)") {x=3;y=1} else {x=2;y=0}; {print $(NF-x) " " $(NF-y) } }' \
| sort -n -u \
| numfmt --field=1 --to=iec
输出
...
....
129M /var/log/maillog
166M /var/log/nginx/access_log
172M /var/log/metrics/kubernetes/kubelet.log
185M /var/log/metrics/kubernetes/etcd.log
257M /var/log/metrics/kubernetes/etcd.log.1
335M /var/log/metrics/kubernetes/kubelet.log.1
我知道这并不完美。例如,如果文件名包含“DEL”,这将从输出列表中清除该文件。
lsof
还有一个-F
选项中描述的其他程序的输出部分。使用它可能会更简单。
细节
lsof
打印类似这样的内容:
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root cwd DIR 253,0 4096 128 /
tuned 2975 root 7u REG 253,0 4096 805307770 /tmp/ffiKkVeXD (deleted)
python2 49888 49890 root DEL REG 0,18 196039884 /dev/shm/sem.NXPFow
systemd 1 root mem REG 253,0 90664 10063 /usr/lib64/libz.so.1.2.7
java 149435 175229 box 69r REG 253,0 350872273 808108999 /box/var/log/metrics/kubernetes/kubelet.log.1
java 149435 149580 box 107w FIFO 0,8 0t0 272526226 pipe
prometheu 147867 148211 root mem REG 253,6 31457463 /lib64/ld-2.12.so (stat: No such file or directory)
grep REG
保留常规文件
grep -v "stat: No such file or directory"
删除有统计错误的文件。 (我不知道为什么会出现这种情况)
grep -v DEL
丢弃已删除的Linux映射文件;
来自 lsof文档:
''DEL'' 表示已删除的 Linux 映射文件;
经过这个处理后,我们得到这样的结果:
tuned 2975 root 7u REG 253,0 4096 805307770 /tmp/ffiKkVeXD (deleted)
systemd 1 root mem REG 253,0 90664 10063 /usr/lib64/libz.so.1.2.7
java 149435 175229 box 69r REG 253,0 350872273 808108999 /box/var/log/metrics/kubernetes/kubelet.log.1
大小是倒数第三列或第二列,具体取决于最后一列的值。如果最后一列(deleted)
选择倒数第三列,否则选择第二列。
awk '{if ($NF=="(deleted)") {x=3;y=1} else {x=2;y=0}; {print $(NF-x) " " $(NF-y) } }'
sort -n -u | numfmt --field=1 --to=iec
对字节数进行排序、唯一化并使人类可读
答案2
您可以使用-F
选项lsof
来获取几乎明确的输出,可以被机器解析,只有中等程度的痛苦。输出不明确,因为lsof
将文件名中的换行符重写为\n
.
输出lsof
每行包含一个字段。每个名称的第一个字符表示字段类型,该行的其余部分是字段值。这些字段是:p
=PID(仅适用于给定进程中的第一个描述符)、f
=descriptor、t
=type(REG
对于常规文件,唯一具有大小的类型)、s
=size(仅当可用时)、n
=name。下面的 awk 代码收集具有大小的条目并打印大小和文件名。其余管道对输出进行排序并保留最大尺寸的条目。
lsof -Fnst | awk '
{ field = substr($0,1,1); sub(/^./,""); }
field == "p" { pid = $0; }
field == "t" { if ($0 == "REG") size = 0; else next; }
field == "s" { size = $0; }
field == "n" && size != 0 { print size, $0; }
' | sort -k1n -u | tail -n42 | sed 's/^[0-9]* //'
答案3
您可以执行以下操作
lsof | grep REG | awk '{ print $1,$7,$9 }' | sort -t ' ' -k 2 -V
使用 awk 过滤输出以包括命令、大小和文件名,并根据第二列(即大小)对其进行排序。 -t指定分隔符,-V“自然”排序 - 因此 1, 2, 10 将以这种方式排序,而不是 1, 10, 2。-k是排序的键(您要排序的列)