Rate this page

List all open file descriptors for a given process

Tested on

Debian (Etch, Lenny, Squeeze)
Fedora (14)
Ubuntu (Hardy, Intrepid, Jaunty, Karmic, Lucid, Maverick, Natty, Precise)

Objective

List all files descriptors for a given process

Background

Open files are accessed by means of file descriptors. Each descriptor belongs to a particular process. There may be several descriptors that refer to the same file, belonging to the same or different processes. The file remains open until all file descriptors that refer to it have been closed.

Scenario

Suppose you know that a particular daemon process writes error messages to stderr. You suspect that this has been redirected to a logfile, and wish to discover the pathname of that logfile.

Method

You can obtain a list of file descriptors from /proc, but you first need to know the PID (process ID) of the process in question. This can be found using the ps command.

If you know the name of the file that the process is executing then you can use the -C option to find the PID:

ps -C postgres

Alternatively, you can to list all processes and search for the one that is wanted:

ps -e

Some daemons spawn several copies of themselves. For the particular scenario considered here it would be reasonable to assume that all instances write to the same logfile. For more complex troubleshooting you may want to reconfigure the daemon to spawn one instance only (if this is possible).

Suppose you determine that the process of interest has a PID of 12345. Information about this process can be found in /proc/12345/, and information specifically about its file descriptors in /proc/12345/fd/. Each file descriptor is presented as a softlink to the corresponding file. You can inspect these softlinks using the ls command:

ls -l /proc/12345/fd/

The output from this command might look similar to:

lr-x------ 1 postgres postgres 64 2010-12-17 17:54 0 -> /dev/null
l-wx------ 1 postgres postgres 64 2010-12-17 17:54 1 -> /var/log/postgresql/postgresql-8.3-main.log
l-wx------ 1 postgres postgres 64 2010-12-17 17:54 2 -> /var/log/postgresql/postgresql-8.3-main.log
lrwx------ 1 postgres postgres 64 2010-12-17 17:54 3 -> socket:[1032148]
l-wx------ 1 postgres postgres 64 2010-12-17 17:54 4 -> /dev/null
l-wx------ 1 postgres postgres 64 2010-12-17 17:54 5 -> /dev/null
lrwx------ 1 postgres postgres 64 2010-12-17 17:54 6 -> socket:[1032150]
lrwx------ 1 postgres postgres 64 2010-12-17 17:54 7 -> socket:[1032158]

This tells you that file descriptors 1 and 2 (stdout and stderr) are redirected to the file /var/log/postgresql/postgresql-8.3-main.log.

Note that file descriptors 3, 6 and 7 in this example correspond to network sockets so do not have pathnames. Pipes are presented in a similar manner.

Troubleshooting

See Mounting /proc.

Tags: process