Linux – Sort deleted (but still open) files by size

filesystemslinuxprocess

This gives you list of deleted files in your filesystem occupying space (as still open):

find /proc/*/fd -ls 2>/dev/null | grep '(deleted)'

However piping filenames of file descriptors return size 0 :

find /proc/*/fd -ls 2>/dev/null | grep '(deleted)' \
    | sed 's!.*\(/proc[^ ]*\).*!\1!' | xargs ls -lhas

As they have still content , using wc -c provides the size :

find /proc/*/fd -ls 2>/dev/null | grep '(deleted)' \ 
     | sed 's!.*\(/proc[^ ]*\).*!\1!' | xargs wc -c | sort -nr |head -n 20

Example:

2809946696 total
2387677184 /proc/15050/fd/26
  67108864 /proc/1626/fd/23
  67108864 /proc/1059/fd/6
  10485760 /proc/11417/fd/298
  10485760 /proc/11417/fd/239
  10485760 /proc/11417/fd/155
  10485760 /proc/11366/fd/499

However, is there a better way (than wc -c of file descriptors marked as (deleted)) to find out which files occupy most space?
(or even better, which process occupy most space as keeping open handles to deleted files?)

Best Answer

With zsh,

ls -lLrS /proc/*/fd/*(-l0)

would list them ordered by file size (like wc -c, so not disk usage).

For disk usage, you can do:

zmodload zsh/stat
bydu() zstat -A REPLY +block -- $REPLY
ls -lLsU /proc/*/fd/*(-l0no+bydu)

(assuming GNU ls for it's -U for not sorting)

For a disk usage per process, you could do:

typeset -aU proc=(/proc/*/fd/*(-l0.:h:h:t))
for p ($proc) {du -Hksc /proc/$p/fd/*(-.l0) | sed -n "\$s/total\$/$p/p"} | sort -n

(here in kibibytes)

Related Question