Trace a Running Process with peekfd
peekfd watches the bytes a running Linux process reads or writes on one file descriptor, without stopping the process or touching its files. It is a narrow, temporary window onto a process's I/O: a program writing a request to a terminal, or a helper reading from a pipe.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about 10 minutes for a first investigation. You need the psmisc package, a process that stays alive while you attach to it, and enough permission to trace it. The examples below only observe a process you own.
Before you start
This guide describes the version installed on the reference machine: PSmisc 23.7, from Ubuntu package psmisc 23.7-1build1. Check yours before relying on an option:
peekfd --version
peekfd --help
The version command prints a PSmisc version string. The local manual uses -v in its option list, while the synopsis shows the long form as --version. Use whichever spelling your installed binary accepts.
1. Find the process and its descriptors
peekfd takes a process ID first, followed by zero or more descriptor numbers. Start with a process you own and identify its open descriptors:
ps -f -p <PID>
ls -l /proc/<PID>/fd
Replace <PID> with digits for a real running process. The links in /proc/<PID>/fd show which numbers point at a terminal, pipe, socket or regular file. That directory is for finding descriptor numbers; peekfd itself never reads it as input.
Descriptor 0 is normally standard input, 1 standard output and 2 standard error, but do not assume a service follows that convention. A daemon may close them, redirect them to a log, or use other descriptors entirely for its useful traffic.
2. Attach to one descriptor
Give peekfd the PID and the descriptor you want to inspect:
peekfd <PID> 1
The command stays attached while it intercepts reads and writes, and it prints headers identifying the source of each dump unless you add -n. The output can therefore mix the program's own bytes with peekfd's labels: this is observation, not a clean protocol decoder.
For a quieter capture, suppress those headers:
peekfd -n <PID> 1
Tip
Stop the observation with Ctrl-C. That stops peekfd, not the traced process. If the target exits first, the manual warns that peekfd may fail because the process has disappeared.
3. Inspect all descriptors only when you need to
Omitting descriptor arguments asks peekfd to dump activity for every descriptor:
peekfd <PID>
This is often noisy, and it can expose data from more channels than you intended, including credentials or application content. Prefer one known descriptor, or a short list:
peekfd <PID> 0 1 2
Warning
Before using the broad form on a production process, consider who can see your terminal, shell history and captured output. peekfd provides no redaction or filtering layer of its own.
4. Choose output handling deliberately
Most investigations can start with normal output. Add -8 when every byte matters and you do not want post-processing:
peekfd -8 -n <PID> <FD>
That is useful for binary traffic, but your terminal may react badly to control bytes. Redirecting to a file preserves the capture for later inspection, but it also creates a copy of whatever data the process emits:
peekfd -8 -n <PID> <FD> > /tmp/peekfd-capture.bin
Warning
Treat that file as sensitive. Remove it after checking it if it contains private data, and do not upload it to a ticket or paste service without approval.
If a terminal with echo enabled makes read and write lines look duplicated, try -d:
peekfd -d <PID> <FD>
5. Follow child processes when the workload forks
Use -c when the requested descriptor activity should also be dumped from new child processes:
peekfd -c <PID> <FD>
This helps with a launcher that hands work to short-lived children, but it also expands the amount of output and the amount of data visible on your terminal. Start without -c while you are still working out which process owns the activity.
Permission failures and safer recovery
An attachment can fail even when the PID is correct. The manual reports this as Error attaching to pid <PID> and says you may need to be root. Common causes: tracing a process owned by another user, a restrictive system tracing policy, or a target that exited between ps and peekfd.
First check the process still exists and that you own it:
ps -o user=,pid=,stat=,cmd= -p <PID>
Warning
Do not immediately reach for sudo. Elevated tracing can reveal secrets handled by the target, so use it only with explicit authority and a narrow descriptor selection:
sudo peekfd -n <PID> <FD>
There is no service restart or persistent configuration change to undo. Press Ctrl-C to detach, and discard any capture file that is no longer needed.
Common traps
- The target is too short-lived. Attach to a long-running parent or arrange a safe reproduction with a pause. A PID can be valid when listed and gone by the time peekfd attaches.
- The wrong descriptor was selected. Re-read
/proc/<PID>/fd; descriptor numbers are specific to that process. - The output looks duplicated. Terminal echo can make the same interaction appear more than once. Try
-d, but keep the raw form if exact byte order matters. - Binary bytes wreck the terminal display. Stop with
Ctrl-C, then repeat with-8redirected to a file rather than a terminal. - Nothing useful appears. peekfd only reports reads and writes made while it is attached. It cannot show earlier activity, and a descriptor may simply be idle during your capture.
Done means
- Confirmed the tool. You checked the installed PSmisc version and help output.
- Identified the target. You found the PID and descriptor from
/proc/<PID>/fd. - Scoped the capture. You captured only the required descriptor, or consciously accepted the wider output.
- Cleaned up safely. You stopped peekfd with
Ctrl-Cand handled any capture file as sensitive data.