web-dev-qa-db-ja.com

最大の開いているファイルを見つける方法は?

すべてのプロセスが開いているファイルの中で最大のものを探します。 lsofには既にサイズが指定された開いているファイルがあります。正しいパラメータをlsofに渡し、出力を処理している可能性があります。

9
Hakan Baba

lsof-Fオプションを使用して、 中程度の痛みのみでマシン解析可能なほぼ明確な出力 を取得できます。 lsofはファイル名の改行を\nに書き換えるため、出力があいまいです。

lsof出力は、1行あたり1つのフィールドで構成されます。各名前の最初の文字はフィールドタイプを示し、行の残りの部分はフィールド値です。フィールドは、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]* //'

複雑な方法の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"_ statエラーのあるファイルを削除します。 (なぜこれが起こるのか分かりません)


_grep -v DEL_削除されたLinuxマップファイルを破棄します。

Lsofから documentation

削除されたLinuxマップファイルの '' DEL '';


この処理の後、次のようなものが残ります。

_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
_

サイズは、最後の列の値に応じて、最後から3番目または2番目の列です。最後の列が_(deleted)_の場合、最後から3番目、それ以外の場合は2番目を選択します。

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_

ソート、一意化、バイト数を人間が読めるようにする

5
Hakan Baba

次のことができます

lsof | grep REG | awk '{ print $1,$7,$9 }' | sort -t ' ' -k 2 -V

Awkを使用して、コマンド、サイズ、およびファイル名を含めるように出力をフィルタリングし、サイズである2番目の列に基づいてソートします。 -t区切り文字を指定します-V「自然に」ソートします-したがって、1、2、10は1、10、2ではなくこの方法でソートされます-kはソートのキーです(ソートしたい列)

4
Chen A.