How can I print file names on linux command if know its file descriptor of a file opened by a process?

Posted on

Problem :

I know the file descriptor of a file opened by a process, but I don’t know the process ID. How can I print file names from the Linux command prompt if I know the file descriptor of a file opened by a process?

Solution :

If you do not know the process ID, you will have to check all processes that have the same fd# open, since file descriptors are not globally unique. The smaller the fd#, the more processes will have it open (e.g. on my system, even if the fd# is around 30, I’d still need to guess between 15 processes, and if I was looking for fd# around 10, then the list would have ~170 processes).

The proc filesystem shows the file descriptors as symlinks under /proc/<pid>/fd.

# ls -l /proc/1/fd
lrwx------ 1 root root 64 Feb 12 22:10 /proc/1/fd/0 -> /dev/null
lrwx------ 1 root root 64 Feb 12 22:10 /proc/1/fd/1 -> /dev/null
lrwx------ 1 root root 64 Feb 12 22:10 /proc/1/fd/2 -> /dev/null
l-wx------ 1 root root 64 Feb 12 22:10 /proc/1/fd/3 -> /dev/kmsg
lrwx------ 1 root root 64 Feb 12 22:10 /proc/1/fd/4 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 Feb 12 22:10 /proc/1/fd/5 -> anon_inode:[signalfd]
lr-x------ 1 root root 64 Feb 12 22:10 /proc/1/fd/6 -> /sys/fs/cgroup/systemd/
...etc...

For example, to look for fd #5 in all processes:

# ls -l /proc/*/fd/5
lrwx------ 1 root    root    64 Feb 12 22:10 /proc/1/fd/5 -> anon_inode:[signalfd]
lrwx------ 1 root    root    64 Feb 12 22:15 /proc/129/fd/5 -> socket:[6980]
lrwx------ 1 root    root    64 Feb 12 22:15 /proc/168/fd/5 -> socket:[7847]
lrwx------ 1 root    root    64 Feb 12 22:15 /proc/341/fd/5 -> anon_inode:[eventfd]
lr-x------ 1 root    root    64 Feb 12 22:15 /proc/342/fd/5 -> anon_inode:inotify
...etc...

The exact interface to resolve symlink targets is readlink():

# readlink /proc/427529/fd/7
/home/grawity/lib/dotfiles/vim/backup/%home%grawity%.bashrc.swp

From the lsof manpage:

To find the process that has /u/abe/foo open, use:

lsof /u/abe/foo

See also this tutorial on lsof ans these hints on lsof

Leave a Reply

Your email address will not be published. Required fields are marked *