When examining file descriptors in Linux's /proc/[pid]/fd
directory, you'll frequently encounter entries like:
l-wx------ 1 root root 64 Jul 30 15:14 10 -> pipe:[90222668]
lr-x------ 1 root root 64 Jul 30 15:14 11 -> pipe:[90222669]
These represent interprocess communication pipes, where the number in brackets (e.g., 90222668) is the kernel's inode identifier for the pipe.
To identify processes sharing a pipe, use this bash command sequence:
# Find all processes with the specific pipe open
grep -l 'pipe:[90222668]' /proc/*/fd/* 2>/dev/null |
while read -r link; do
pid=${link#/proc/}
pid=${pid%/fd*}
echo "Process $pid has fd $(basename $link) connected to pipe 90222668"
ps -p "$pid" -o comm=,pid=,cmd=
done
This script will output all processes holding file descriptors connected to the specified pipe, along with their command lines.
The lsof
command can provide similar information more conveniently:
lsof | grep '90222668'
Sample output would show:
python3 1234 user 3w FIFO 0,13 0t0 90222668 pipe
bash 5678 user 4r FIFO 0,13 0t0 90222668 pipe
While you can't directly read from pipes in /proc (as they're kernel objects), you can:
- Trace the processes using strace:
strace -p 1234 -e trace=read,write -s 80
- Use gdb to attach to the process and inspect file descriptors
Let's walk through a real-world debugging scenario:
# First, find all pipe connections for a specific process
ls -l /proc/12345/fd | grep pipe
# Output shows:
# 5 -> pipe:[87654321]
# Now find the other end
lsof | grep 87654321
# Output reveals:
# app1 12345 user 5w FIFO 0,13 0t0 87654321 pipe
# app2 67890 user 7r FIFO 0,13 0t0 87654321 pipe
This shows process 12345 (app1) has FD 5 writing to the pipe, while process 67890 (app2) has FD 7 reading from it.
For persistent monitoring of pipe activity:
# Set up inotify watch on the pipe
inotifywait -m /proc/12345/fd -e open |
while read -r dir action file; do
if [[ "$file" == pipe* ]]; then
echo "New pipe connection: $(readlink "/proc/12345/fd/$file")"
fi
done
Remember that pipes are unidirectional - one process writes while another reads, which explains the different permissions shown in the original ls -l
output (w vs r).
When examining file descriptors in /proc/<pid>/fd
, you'll frequently encounter entries like:
l-wx------ 1 root root 64 Jul 30 15:14 10 -> pipe:[90222668]
lr-x------ 1 root root 64 Jul 30 15:14 11 -> pipe:[90222669]
These represent anonymous pipes created between processes. The number in square brackets is the kernel's internal inode number for the pipe.
To identify both ends of a pipe connection:
# Find all processes with open pipes
find /proc -type l -name '[0-9]*' -exec ls -l {} + | grep 'pipe:\[' | sort
This command scans all processes' file descriptors for pipe references. Matching inode numbers indicate connected pipes.
The lsof
utility provides detailed pipe information:
# Install if needed
sudo apt install lsof
# Show all open pipes
lsof | grep FIFO
# Filter for specific pipe inode
lsof | grep '90222668'
For deeper analysis, use SystemTap to trace pipe operations:
# SystemTap script to track pipe creation
probe syscall.pipe {
printf("Pipe created by PID %d (%s)\n", pid(), execname())
}
probe syscall.pipe2 {
printf("Pipe2 created by PID %d (%s)\n", pid(), execname())
}
For kernel developers, pipe details are available in the pipefs filesystem:
# Requires debugfs mounted
cat /sys/kernel/debug/pipe_info
# Alternative via /proc (if configured)
cat /proc/<pid>/fdinfo/10