Read Descriptor Detail from /proc/pid/fdinfo

/proc/<pid>/fdinfo goes one level deeper than a plain descriptor listing, down to the file offset and open flags. The examples use Linux 6.8.0-139-generic and the locally installed Linux man-pages 6.7 package.

Allow about ten minutes. You need a shell and a mounted /proc filesystem. The workflow is read-only and normally needs no elevated privileges: it does not close a descriptor, change a flag, signal a process or alter a file.

1. Confirm the procfs entry

Each process has a directory named by its process ID. Its fdinfo subdirectory holds one file per open descriptor, named by the descriptor number. Start with your own shell, where permission is least surprising:

$ test -d /proc/self/fdinfo && echo fdinfo-is-available
fdinfo-is-available
$ printf 'shell PID: %s\n' "$$"
shell PID: 28417

The PID differs on every run. /proc/self is the right spelling when the command reading the file should inspect itself. Use /proc/PID to inspect another process, replacing PID with digits from your system.

2. List descriptors before reading one

List the numeric entries to see which descriptors exist:

$ find /proc/self/fdinfo -maxdepth 1 -type f -printf '%f\n' | sort -n
0
1
2
9

Your list depends on the shell, terminal and inherited descriptors. Do not assume descriptor 3 or 9 exists. A descriptor can disappear between listing and reading if the process closes it, so a brief No such file or directory failure is normal for a busy process.

Checkpoint: pick a number that appeared in your own listing. The next command uses 0, since standard input is normally present.

$ cat /proc/self/fdinfo/0
pos:\t0
flags:\t0100000
mnt_id:\t26

Values are host-specific. The shape to look for is a decimal pos, an octal flags value and a mount ID. A terminal, pipe or redirected file produces different numbers.

3. Read the common fields

Read a known descriptor repeatedly when you are checking a live process:

$ while IFS= read -r line; do printf '%s\n' "$line"; done < /proc/self/fdinfo/0
pos:\t0
flags:\t0100000
mnt_id:\t26

This reads a snapshot of the pseudo-file. It does not lock the descriptor or freeze the process. For a coherent application-level view, collect the process's own diagnostics or trace its behaviour, do not treat two separate reads as one transaction.

4. Correlate a mount ID without changing anything

mnt_id is an identifier, not a path. To see the corresponding mount entry, search the target process's mountinfo file:

$ mount_id=26
$ awk -v id="$mount_id" '$1 == id { print }' /proc/self/mountinfo
26  ... - ext4 /dev/nvme0n1p3 rw,relatime

The full line contains namespace and mount relationships before the separator, followed by the filesystem type and mount options. The example is abbreviated because the device and mount options belong to the host. No matching line usually means a copied number is wrong, or you are reading a different process's files: different mount namespaces can legitimately show different mount tables.

5. Recognise descriptor-specific records

The common fields are not the whole interface. The kernel adds records according to what the descriptor refers to.

pos:    0
flags:  02004002
mnt_id: 13
clockid: 0
ticks: 0
settime flags: 03
it_value: (7695568592, 640020877)
it_interval: (0, 0)

Do not parse every line as a key and a decimal value. The record format varies by descriptor type, and several fields are hexadecimal or structured tuples. Identify the kind of descriptor first, from the program or its /proc/PID/fd symbolic link, then apply the matching section of proc_pid_fdinfo(5).

6. Handle permissions and changing processes

fdinfo files are readable only by the process owner. Reading your own process is the simplest test. For another user's process, the read can fail even when the PID is correct:

$ cat /proc/OTHER_PID/fdinfo/0
cat: /proc/OTHER_PID/fdinfo/0: Permission denied

Replace OTHER_PID only with a real PID when testing.

Warning: do not reach for sudo as a reflex. Elevated access may be restricted by the system's ptrace policy, and reading a sensitive process can expose operational details. Get authorisation before inspecting another user's process, and avoid copying descriptor data into tickets or logs where it might reveal file or device state.

A PID can also be reused after a process exits. If the target matters, record its command name and start time, and repeat the identity check close to the read. A descriptor number is meaningful only inside its own process: descriptor 4 in one process has no relationship to descriptor 4 in another.

Done means