Read Linux Process and System State Through /proc
Every ps, top and kill you have run was quietly reading and writing through /proc on your behalf. This guide covers a small set of read-only commands for inspecting processes, threads and system state directly, plus a safe way to reason about the privacy-related hidepid mount option. The examples follow the locally installed proc(5) manpage from the Debian manpages package, version 6.7-2. The procfs(5) name you may see referenced elsewhere is an alias for the same documentation.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell. Ordinary inspection needs no elevated privileges on a normally mounted proc filesystem. Do not remount /proc on a live host just to try an example here: mount changes can hide process information from monitoring, diagnostics or other services.
1. Confirm what is mounted
Start by checking that the path is actually a proc filesystem, and record its current options:
$ findmnt -no TARGET,FSTYPE,OPTIONS /proc
/proc proc rw,relatime
Your options may differ. The parts that matter are the target, the proc filesystem type, and any privacy option such as hidepid=1 or hidepid=2. If findmnt reports nothing at all, look at the mount setup before assuming individual files are missing. The manpage describes /proc as commonly mounted automatically, though it can be mounted by hand too.
Checkpoint
Leave this output unchanged. It is your baseline if someone else later changes the mount.
2. Use the process links instead of hard-coding a PID
/proc/self resolves to whichever process accesses the link. /proc/thread-self resolves to that process's current thread directory. Ask the shell to resolve both:
$ readlink /proc/self
540446
$ readlink /proc/thread-self
540446/task/540446
Those numbers come from one process and will differ on your machine. A common mistake is treating the first number as a stable identifier: it is only the PID of whichever process did that particular read. A program that opens /proc/self sees itself, never the shell that launched it.
For a stable reference across one shell session, save the shell's own PID and use it explicitly:
pid=$$
printf 'shell PID: %s\\n' "$pid"
readlink "/proc/$pid"
cat "/proc/$pid/status" | sed -n '1,8p'
Expect a numeric PID followed by the first fields of status, such as Name, Umask and State. The exact fields and values belong to your running kernel and process.
3. Inspect process and thread directories
A numeric directory such as /proc/1234 describes the process with PID 1234. The task directory underneath holds one numeric directory per thread, keyed by thread ID:
pid=$$
printf 'process: %s\\n' "$pid"
ls -ld "/proc/$pid" "/proc/$pid/task"
printf 'threads:\\n'
find "/proc/$pid/task" -mindepth 1 -maxdepth 1 -type d -printf '%f\\n' | sort -n
The process directory and its task directory should exist for as long as the shell is running. A multithreaded program will normally show several thread IDs. Here is the surprising bit: the top-level /proc listing exposes process directories when you iterate it, but the separate /proc/TID thread paths never show up in a plain ls /proc. That is exactly why a thread can be perfectly addressable without ever appearing as another top-level process.
For a quick system-wide view, list only numeric entries and avoid mistaking names such as self for PIDs:
find /proc -maxdepth 1 -mindepth 1 -type d -regex '/proc/[0-9]+' -printf '%f\\n' | sort -n | head
Processes can exit between discovery and inspection. A later No such file or directory is normal for a short-lived process, not proof that procfs is broken.
4. Read system-wide files as snapshots
Names beginning with letters describe system-wide information. Read a small, portable pair of examples:
$ cat /proc/uptime
1295799.30 9058997.30
$ sed -n '1,12p' /proc/meminfo
MemTotal: 16317888 kB
MemFree: 1234567 kB
Those values are illustrative and will not match your host. /proc/uptime holds the uptime and cumulative idle time in seconds. /proc/meminfo exposes memory counters, names and values separated by whitespace. Read these files again whenever a decision depends on them: procfs is a live interface, not a frozen report, so a single read is only a snapshot of changing kernel state.
Reach for a tool that already interprets a file when you actually need human-friendly output; free exists precisely for memory reporting. Read the underlying proc file when you are diagnosing what the kernel interface really exposes, or writing a small, controlled script.
5. Decode null-separated process data
Some proc files store strings in an internal format. The manpage specifically calls out command lines and environments here: their fields end with null bytes rather than newlines. Convert those separators before you read them, using the shell's own PID so the process you inspect cannot change mid-command:
$ tr '\000' '\n' < "/proc/$$/cmdline"
/bin/bash
-c
tr '\000' '\n' < "/proc/$$/cmdline"
Your command line will differ, and an empty-looking line or a command that alters its own visible arguments is also possible. Do not assume command-line data is secret: other local users may be able to read it unless the proc mount is restricted, and programs can deliberately change what they display.
Avoid an unquoted variable in a proc path, which matters more once a PID comes from another command:
pid='1234'
if [ -r "/proc/$pid/status" ]; then
sed -n '1,12p' "/proc/$pid/status"
else
printf 'PID %s is no longer readable\\n' "$pid" >&2
fi
Replace 1234 with a PID you have deliberately chosen. The read can still fail after the test passes, if the process exits or permissions change in between. Treat that as an ordinary race, not a bug.
6. Understand privacy controls before changing them
The proc filesystem supports hidepid=0, hidepid=1 and hidepid=2. The default is 0 when the option is absent, meaning every user can access every process directory. Mode 1 leaves directories visible but restricts files and subdirectories belonging to other users. Mode 2 goes further and hides other users' process directories during normal directory iteration too.
A proc mount can also use gid=GROUP. Members of that group can access process information that hidepid would otherwise block, and the manpage recommends exactly this group-based approach instead of dropping non-root users into sudoers just so they can read process information.
Warning
Do not copy a remount command into production without checking service and monitoring dependencies first. Changing hidepid can break process discovery, diagnostics and any script that expects another user's /proc/PID files to be readable. If an administrator has already changed it, the recovery is to restore the previous mount options through the host's documented mount configuration and maintenance procedure. Capture the output of findmnt before making any change; never guess the old options.
Even hidepid=2 is not a complete process-existence barrier. The manpage notes that a known PID can still be tested by other means, such as kill -0, and that a process may reveal itself through other behaviour anyway. Treat the setting as information reduction, not a replacement for access control or application-level secrecy.
7. Check the common failure modes
- Permission denied: check the mount options and the identity running the command. Elevated privileges may suit an approved diagnostic, but
sudodoes not make a missing process reappear. - Missing PID: retry the lookup. The process may have exited between listing
/procand opening its file. - Unexpected command-line text: use
tr '\000' '\n'and remember that/proc/selfbelongs to the reader, not the caller. - Missing thread in the top-level listing: inspect
/proc/PID/taskinstead. Thread IDs live there, not among the entries returned by normal iteration of/proc. - A writable proc file: stop and identify exactly what it controls. Most proc files are read-only, but some writable ones change kernel variables, so never write to one from a copied example.
Done means
- Recorded the current
/procfilesystem and mount options withfindmnt. - Distinguished
/proc/self,/proc/thread-self, process directories and thread directories. - Read a system snapshot and decoded null-separated command-line data without confusing the reader process with the target.
- Understood what each
hidepidmode changes and did not remount a live system casually.