The Process Tree
You saw the PPID column in the last chapter’s ps preview without a real explanation. Every process on a Linux system — except exactly one — was started by another process, and that relationship isn’t incidental bookkeeping. It’s the structure that explains where processes come from, what happens when one disappears unexpectedly, and what a zombie actually is.
No Process Creates Itself
When you run a command in your shell — say, ls — your shell doesn’t transform into ls. Instead, it makes a copy of itself (a step the kernel calls forking), and that copy then replaces itself with the ls program (a step called exec‘ing). The result: your original shell process is still there, now referred to as the parent, and a brand new ls process exists as its child.
You don’t need to memorize the words “fork” and “exec” as commands you’ll type — they’re kernel-level mechanisms, not tools you reach for directly. What matters practically is the outcome: every process has exactly one parent, recorded as that PPID (Parent Process ID) you saw in the last chapter, and that parent is whatever process actually launched it.
flowchart TB
A["bash (PID 1000)"] -->|"forks, then execs"| B["ls (PID 1042)<br/>PPID = 1000"]
A -->|"forks, then execs"| C["cat (PID 1043)<br/>PPID = 1000"]
Run any command from your shell and you’re watching this happen, every single time, whether you notice it or not.
Seeing The Whole Tree: pstree
ps shows you a flat list. pstree shows the same information arranged as an actual tree, making parent-child relationships visible at a glance instead of something you’d have to reconstruct manually by cross-referencing PID and PPID columns.
pstreeYou’ll see something shaped roughly like this:
systemd─┬─sshd───bash───pstree
├─cron
└─systemd-journaldRead it left to right: systemd is the ancestor of everything, sshd (the SSH service that let you log in) is its child, your login shell bash is sshd’s child, and pstree itself — the very command you just ran — shows up as bash’s child, since your shell is what spawned it.
Add -p to show PIDs alongside each process name, which is often what you actually want once you’re using this for real troubleshooting rather than just getting oriented:
pstree -pPID 1: The One Process With No Parent
Every process traces back through its chain of parents eventually, and that chain always ends at the same place: PID 1, which — as mentioned in the last chapter — is systemd on nearly every modern Linux distribution. PID 1 is the only process on the entire system with no parent of its own; it’s started directly by the kernel during boot, before any other process exists to have started it.
This is why pstree output always roots itself at systemd (or occasionally init, an older equivalent name for the same role on some systems) — there’s nowhere higher in the hierarchy to go.
What Happens When A Parent Dies First: Orphans
Normally, a parent outlives its children, or at least is still around when they finish. But processes can and do outlive their parents — if you close a terminal while a background command is still running, for instance, that command’s original parent shell no longer exists.
When this happens, the child becomes an orphan, and the kernel doesn’t just leave it parentless — it’s automatically reparented, typically straight to PID 1. systemd effectively adopts every orphaned process on the system, which is exactly why the process tree always stays a proper tree with a single root, no matter how many original parent shells have long since exited.
Important
Normally exiting a parent process causes its surviving children to be reparented, typically to PID 1 (systemd). However, if the parent is terminated with signals such as SIGKILL, or the terminal/session is closed through the UI, its child processes may also be terminated rather than surviving to be reparented.
Zombies, Properly Explained
The last chapter named zombie state without fully explaining it — this is the piece that was missing. When a process finishes, it doesn’t disappear from the system instantly. The kernel keeps a small remnant of it around — its exit status, essentially “here’s how it ended” — and that remnant stays until the parent explicitly checks in and collects it, a step referred to as reaping.
A zombie is a process that has finished executing but is still waiting to be reaped by its parent. It’s not consuming CPU or memory in any meaningful sense — it’s essentially just an entry in the process table waiting for its parent to acknowledge it’s done. This is normal and extremely short-lived in virtually every case; a well-behaved parent process reaps its children almost immediately.
Zombies become a genuine problem only when a parent process is buggy and never reaps its children at all — the zombie entries pile up over time, and since the process table has a finite size, enough accumulated zombies can eventually prevent new processes from being created at all.
Note
You cannot kill a zombie process directly — there’s nothing left running to send a signal to; it’s already finished. The only real fix is for the parent to reap it (which a properly working parent does automatically) or, if the parent itself is the problem, to deal with the parent instead. This is one of the rare situations where kill, covered later in this section, is the wrong tool entirely.
A Real Example: Watching Reparenting Happen
You can observe reparenting directly from your normal Bash/login shell.
1. Start a background process
Run:
sleep 400 &Note the PID printed by the shell.
2. Find its parent
Use the PID you noted:
ps -o pid,ppid,cmd -p <sleep PID>You should see something like:
PID PPID CMD
1235 1200 sleep 400The PPID is the PID of your current shell.
3. Exit the shell
Now exit that shell:
exitYour shell terminates, but if sleep survives the shell’s exit, it becomes an orphan.
4. Open a new terminal
Start a new terminal and run:
ps -o pid,ppid,cmd -p <sleep PID>You should now see:
PID PPID CMD
1235 1 sleep 400Notice that the PID of sleep is unchanged, but its PPID has changed from your old shell’s PID to 1.
This is reparenting: the child outlives its parent, so the kernel reparents it to PID 1 (systemd). This may not always be PID 1 but PPID will change as you have seen.
Important
Normally exiting a parent process causes its surviving children to be reparented, typically to PID 1 (systemd). However, if the parent is terminated with signals such as SIGKILL, or the terminal/session is closed through the UI, its child processes may also be terminated rather than surviving to be reparented.
Clean up the process when you’re done:
kill <sleep PID>What’s Next
You now understand where processes come from, how the tree is structured, and what happens at both ends of a process’s life — orphaning at the start of an unexpected gap, zombies at the tail end. With that foundation in place, the next chapter gets into the tool you’ve been previewing this whole time in small doses: ps itself, properly, including the flag styles and output columns that make it genuinely confusing the first time you sit down with a real, busy system.