How to use the pstree Command in Linux

pstree takes the flat, scrolling mess that ps gives you and turns it into an actual tree, showing which process spawned which. Instead of hunting through PIDs and PPIDs by hand, you see the parent-child chain laid out in front of you.

pstree Command Syntax





LinuxTeck
pstree [options] [pid | user]

I first reached for pstree years ago while trying to figure out why a cron job kept spawning zombie children on a Rocky Linux box, and ps aux just wasn't giving me the relationship between them fast enough. Once you get comfortable with the flags below, you will start using pstree before ps for anything involving parent-child confusion.

Examples

How to Install pstree in Linux

pstree ships as part of the psmisc package, which is already installed on most desktop distros. If it's missing on a minimal server image, grab it with your package manager below.






LinuxTeck
linuxteck@ubuntu:~$ sudo apt install psmisc
linuxteck@rocky:~$ sudo dnf install psmisc
linuxteck@arch:~$ sudo pacman -S psmisc
Sample Output
Reading package lists... Done
Building dependency tree... Done
psmisc is already the newest version (23.7-1).
0 upgraded, 0 newly installed, 0 to remove.

1. Display the Full Process Tree with the pstree Command

Run pstree with no arguments and it walks every process on the system starting from init or systemd and prints them as a tree, using square brackets to collapse repeated identical branches like threads.






LinuxTeck
linuxteck@ubuntu:~$ pstree
Sample Output
systemd─┬─2*[agetty]
├─containerd───11*[{containerd}]
├─cron
├─dbus-daemon
├─networkd-dispatcher───2*[{networkd-dispat}]
├─nginx───2*[nginx]
├─sshd───sshd───bash───pstree
└─systemd-journald

Square brackets and curly braces mean two different things here. Square brackets like 2*[agetty] mark identical sibling processes that pstree compacted into one line with a repeat count. Curly braces like {containerd} mark threads belonging to that process rather than separate processes, so 11*[{containerd}] reads as eleven identical threads under containerd, not eleven child processes.

2. Show Command-Line Arguments with -a

By default pstree hides the flags a process was started with. Add -a when you need to see exactly how something was invoked, which is handy when you're chasing down which script launched a runaway process.






LinuxTeck
linuxteck@ubuntu:~$ pstree -a
Sample Output
systemd splash
├─cron -f
├─nginx -g daemon on; master_process on;
│ └─nginx -g daemon on; master_process on;
└─sshd -D
└─sshd
└─bash
└─pstree -a

Notice the tree loses the compaction brackets once -a is active, since each process now needs its own line to show its arguments.

3. Display PIDs Next to Each Process with -p

Add -p to print the process ID after every name in parentheses. This is the flag I reach for most, since it lets you jump straight from a visual tree to a ps or kill command without a second lookup.






LinuxTeck
linuxteck@ubuntu:~$ pstree -p
Sample Output
systemd(1)─┬─cron(842)
├─nginx(1190)───nginx(1191)
└─sshd(2201)───sshd(2340)───bash(2341)───pstree(2410)

4. Expand Identical Subtrees with -c

pstree merges identical branches by default to save space. If you actually want to see every worker process listed on its own line instead of collapsed into a count, pass -c to turn that compaction off. Just note that combining -c with -p is redundant, since -p already forces every process onto its own line by disabling compaction on its own.






LinuxTeck
linuxteck@ubuntu:~$ pstree -c
Sample Output
nginx─┬─nginx
├─nginx
├─nginx
└─nginx

Compare that against the collapsed 4*[nginx] style output from example 1. If you also need the PIDs for each worker, use -p on its own instead of stacking it with -c.

5. Sort Child Processes by PID with -n

pstree normally sorts siblings alphabetically by process name. When you're trying to see the order processes were actually spawned in, -n sorts them numerically by PID instead.






LinuxTeck
linuxteck@ubuntu:~$ pstree -np
Sample Output
systemd(1)─┬─dbus-daemon(731)
├─cron(842)
├─nginx(1190)
└─sshd(2201)

6. Show Which User Owns Each Process with -u

Add -u and pstree prints the username in parentheses every time ownership changes down the tree, which makes it obvious when a process is running under a different account than its parent, like a web server dropping from root to www-data.






LinuxTeck
linuxteck@ubuntu:~$ pstree -u
Sample Output
systemd─┬─nginx(root)───nginx(www-data)
└─sshd───sshd(linuxteck)───bash

Production Tip:

On a shared server, running pstree -u is a fast way to spot a process running under the wrong account before it becomes a permissions incident. If you're hosting on a managed platform, this kind of privilege drop is usually handled for you already, which is one of the reasons people move sites to managed stacks like the one covered in this Kinsta review instead of self-managing every worker process.

7. Highlight the Current Process and Its Ancestors with -h

When you run pstree from inside a deep terminal session, it can be hard to spot yourself in a wall of text. The -h flag highlights your current shell and every process above it back to init, assuming your terminal supports highlighting.






LinuxTeck
linuxteck@ubuntu:~$ pstree -h
Sample Output
systemd───sshd───sshd───bash───pstree
(bash and pstree appear highlighted in your terminal)

Concept:

-h relies on your terminal's ANSI escape support to actually draw the highlight. Run it over SSH into a dumb terminal, inside a script, or redirect the output to a file, and pstree silently falls back to plain text with no visible highlighting at all. It's not broken, there's just nothing for it to highlight with.

8. View the Process Tree for a Specific User

pstree accepts a username as its argument and shows only the branches rooted at processes owned by that account, which beats scrolling through a full system tree on a box with dozens of logged-in users.






LinuxTeck
linuxteck@ubuntu:~$ pstree linuxteck
Sample Output
sshd───bash─┬─pstree
└─vim

9. View the Process Tree Rooted at a Specific PID

Pass a PID instead of a username and pstree treats it as the root of the tree, showing only that process and everything spawned underneath it. This is useful once you already know the PID from top or htop and just want to see its children.






LinuxTeck
linuxteck@ubuntu:~$ pstree 1190
Sample Output
nginx─┬─nginx
├─nginx
└─nginx

10. Trace Parent Processes of a PID with -s

Sometimes you need to go the other direction and see what launched a process rather than what it launched. The -s flag shows the full chain of parents leading up to the given PID.






LinuxTeck
linuxteck@ubuntu:~$ pstree -s 2341
Sample Output
systemd───sshd───sshd───bash(2341)

Reading upward like this is often faster than piecing the chain together manually from a raw ps -ef dump, especially in the process management cheat sheet workflow.

11. Passing More Than One PID or Username to pstree

People coming from ps often try to hand pstree a list of targets at once, expecting it to print a tree for each. pstree's own syntax only ever documents a single trailing pid or user slot, not a list, and that has held true across every released version of the tool. Depending on your version, a second target is either ignored or rejected with a usage error, it is not a supported way to get multiple trees.






LinuxTeck
linuxteck@ubuntu:~$ pstree 1190 2341
Sample Output
nginx─┬─nginx
└─nginx
(the second argument, 2341, is not used)

Common Mistake:

pstree only accepts one PID or username as its trailing argument. If you need to check on two or three services at once, run pstree once per target instead of stacking arguments on a single line.






LinuxTeck
linuxteck@ubuntu:~$ pstree 1190; pstree 2341
Sample Output
nginx─┬─nginx
└─nginx
systemd───sshd───sshd───bash(2341)

Separating the two commands with a semicolon runs them back to back regardless of whether the first one succeeds, which is what you actually want when you are just glancing at two unrelated trees.

12. Trace a Zombie Child Back to the Parent That Should Reap It

This is the situation from the intro. pstree does not mark zombie processes with any symbol of its own, that detail still comes from ps, but once you know a PID is stuck in the Z state, pstree is the fastest way to find out which parent owns it, since a zombie cannot be killed directly and only its parent can clear it.






LinuxTeck
linuxteck@ubuntu:~$ ps -eo pid,ppid,stat,comm | awk '$3 ~ /^Z/'
Sample Output
PID PPID STAT COMMAND
4821 4790 Z backup.sh

ps confirms PID 4821 is a zombie and tells you its parent is 4790. Feed that parent PID into pstree with -p to see exactly where it sits in the wider tree, including the cron entry that ultimately kicked it off.






LinuxTeck
linuxteck@ubuntu:~$ pstree -ps 4790
Sample Output
systemd(1)───cron(842)───backup.sh(4790)

Production Tip:

You cannot kill a zombie, there is no running code left to receive a signal. Instead, deal with the parent shown by pstree: if 4790 is still alive and just never called wait() on its child, sending it SIGCHLD is often enough to clear the zombie. If the parent itself is hung, you have to restart or kill that parent, at which point init or systemd adopts and reaps the orphaned zombie automatically. Either way, pstree is what tells you which process to act on instead of guessing.


Questions I Get Asked About pstree All the Time

What's the actual difference between pstree and ps?

ps gives you a flat list of processes with columns of data, while pstree takes that same information and arranges it by parent-child relationship. You'd use the ps command when you need specific fields like CPU or memory, and pstree when you just need to understand the hierarchy fast.

Can pstree kill a process directly?

No, pstree is read only. Once you've found the PID you need with pstree -p, you still hand it off to kill or killall yourself.

Why does my output show something like 4*[nginx] instead of listing each process?

That's pstree's compaction behavior. When several sibling processes have identical command lines, it collapses them into one line with a count instead of repeating the same name over and over. Pass -c if you want them listed individually.


Conclusion

pstree turns a confusing pile of PIDs into something you can actually read at a glance, and once -p and -a become muscle memory you'll reach for it before ps most days. It's also the tool that finally solved that cron zombie mess from the intro, tracing the stuck child back to its parent in one shot instead of piecing it together by hand. If you want the rest of your process toolkit in one place, the system monitoring cheat sheet is a good next stop. Which pstree example do you find most useful? Share your experience in the comments below.

LinuxTeck, A Complete Linux Learning Blog
From your first terminal command to advanced sysadmin skills, every guide here is written in plain English with real examples you can run right now. Explore more in our beginner command guides or check the basic Linux commands library, plus job control with fg and bg and the systemd targets guide for more on how the process tree gets built at boot. For the full flag reference, see the official pstree man page.

Support My Work

Thank you for reading and for being part of this journey. If this article saved you time, consider buying me a coffee. Every contribution helps me keep producing in-depth, practical Linux content for readers like you.

Thank you for your endless support

About Sharon J

Sharon J is a Linux System Administrator with strong expertise in server and system management. She turns real-world experience into practical Linux guides on Linux Teck.

View all posts by Sharon J →

Leave a Reply

Your email address will not be published.

L