Linux Tutorial / PID and PPID Explained: Find and Manage Processes

A PID (process ID) identifies a running process. A PPID (parent process ID) is the PID of the process that created it. On Linux, these numbers help you find a process, inspect its parent-child relationship, and send a signal to a specific process when necessary. The kernel assigns the numbers; you manage the processes they currently identify, not the PID numbers themselves.

What is the difference between a PID and a PPID?

A process is a running instance of a program. Running the same program twice normally creates two processes with different PIDs. When one process creates another, the new process also has a PPID pointing to its parent.

Field Meaning Why it matters
PID The current process's identification number Select a particular process for inspection or signaling
PPID The PID of the current process's parent Identify the creator and inspect parent-child relationships

For example, if a shell has PID 4250 and a sleep process started by that shell has PID 4321, the sleep process may show 4250 as its PPID. These numbers are illustrative. A PID is not a permanent identifier: after a process exits, its number can be reused. In environments with PID namespaces, such as containers, the same process can also appear under different PID numbers depending on where it is observed.

How can you check a process's PID and PPID?

The most direct method is to ask ps for the columns you need. In Bash, $$ expands to the current shell's PID, so the following command displays information about that shell:

ps -p "$$" -o pid,ppid,user,stat,etime,args

The output depends on your environment. PID is the shell's own number, while PPID identifies its parent. USER names the owner, STAT shows process state, ELAPSED shows how long it has been running, and COMMAND or ARGS shows the command.

    PID    PPID USER     STAT     ELAPSED COMMAND
   4250    4110 learner  Ss         00:42 -bash

The numbers and user name above are sample output, not values to expect on your system. You can inspect a known PID with ps -p 4321 -o pid,ppid,args; if that process has exited, no matching process row appears. To list all currently visible processes, use ps -eo pid,ppid,user,stat,args. Pipe a long list to less if you need to browse it.

To find a PID by process name, try pgrep -a -x sleep. The -x option requires an exact process-name match, and -a includes the command line. Several processes may share the same name, so a matching PID alone does not prove you found your own job. The ps command guide and pgrep command guide explain the options in more detail.

Practice: inspect a parent shell and its child

Run the following steps in the same interactive Bash terminal as an ordinary user. sleep 300 simply waits for about five minutes; it does not change system settings or files. Even if other sleep processes exist, this exercise saves the PID of the one you just started.

sleep 300 &
practice_pid=$!
printf 'Shell PID: %s, practice PID: %s\n' "$$" "$practice_pid"
ps -p "$practice_pid" -o pid,ppid,user,stat,etime,args

The & runs the command in the background. In Bash, $! expands to the PID of the most recently started background job, which is saved in practice_pid. After the first line, Bash may also display a job notification such as [1] 4321.

In the ps result, check that the sleep row's PID matches your practice PID and its PPID matches the shell PID. Your actual numbers, user name, and elapsed time will differ.

    PID    PPID USER     STAT     ELAPSED COMMAND
   4321    4250 learner  S          00:02 sleep 300

For another view of the relationship, run ps --ppid "$$" -o pid,ppid,args to list the shell's direct children. If pstree is installed, pstree -p "$$" displays the relationship as a tree. Minimal installations may not include pstree. Also, a short-lived ps or pstree process may itself appear as a child while the list is being collected.

How do you safely request termination by PID?

Knowing a PID is not enough reason to signal it immediately. Because PID numbers can be reused, first check the command, owner, and start time. Run the following promptly in the same shell you used for the exercise:

ps -p "$practice_pid" -o pid,ppid,user,lstart,args
kill -TERM "$practice_pid"
wait "$practice_pid"
ps -p "$practice_pid" -o pid,stat,args

Run kill only after confirming that the first line still identifies your sleep 300 process. TERM (SIGTERM) requests an orderly exit. wait waits for a child created by the current shell; if that child ended because of a signal, wait may return a nonzero status. If the final ps command shows no matching process row, the practice process has exited. If it had already exited before you sent TERM, kill may fail; do not reuse an old practice_pid value.

Despite its name, kill sends a signal to the specified PID. A process that does not respond to TERM can be sent KILL (SIGKILL), but SIGKILL gives it no opportunity to clean up. Recheck the target and cause before considering it as a last resort. See the kill command guide for more on signals.

What happens if a parent exits or a PID changes?

Ending a parent does not necessarily end all of its children. A surviving child can be reparented to another process, so its PPID can change. Do not assume that signaling one parent PID cleans up every process below it.

Conversely, a child that has exited but whose parent has not yet collected its exit status can briefly remain as a zombie process. The child is no longer running, so repeatedly sending KILL to that PID is not the solution. Check how the parent reaps its children. Bash's wait in the exercise is an example of obtaining a child process's exit status.

A PID identifies a process at a particular time. Do not choose a termination target solely from an old PID file or a number written down earlier. Check the command, owner, and start time together. When working inside and outside a container, take care not to confuse PID numbers from different namespaces.

How should you manage a service process?

A service managed by systemd may receive a different PID after it restarts. In that situation, inspect and manage the service unit rather than signaling one PID directly. For example, if nginx.service is actually installed, systemctl status nginx.service checks its status. Use sudo systemctl restart nginx.service only when a restart is operationally appropriate. If nginx is not installed or the system uses another service manager, verify the correct service name and management method first.

A PID helps you identify a particular process; a PPID helps you understand its parent relationship. Before stopping work, narrow down the exact target rather than signaling every process with a matching name. For a managed system service, use its service manager.

Primary references

The ps(1), pgrep(1), pstree(1), and kill(1) manuals describe inspection and signaling. The Bash special parameters and Bash job-control builtins documents explain $$, $!, and wait. See wait(2) for parent termination and zombie processes.

More in This Category
Linux mktemp Command: Create Secure Temporary Files and Directories

Linux mktemp Command: Create Secure Temporary Files and Directories

Learn how to create unpredictable temporary files and directories with Linux mktemp, use templates and TMPDIR, clean up with trap, and avoid unsafe dry runs.

How to Check IP Addresses on Linux

How to Check IP Addresses on Linux

Learn how to check private and public IP addresses on Linux, identify the active interface and route, and distinguish IPv4, IPv6, and externally visible addresses.

Linux Tutorial / How the Shell Runs Commands: ;, &&, ||, Aliases, and Environment Variables

Linux Tutorial / How the Shell Runs Commands: ;, &&, ||, Aliases, and Environment Variables

Learn how Bash resolves commands and uses exit status with ;, &&, and ||, then distinguish aliases, shell variables, and exported environment variables.

Linux Tutorial / File Types and Metadata: ls, file, stat, and readlink

Linux Tutorial / File Types and Metadata: ls, file, stat, and readlink

Learn what ls, file, stat, and readlink each reveal about a Linux file, including type, size, timestamps, and symbolic-link targets.

Linux basename Command: Extract the Final Component of a Path

Linux basename Command: Extract the Final Component of a Path

Learn how to use the Linux basename command to remove directory prefixes and optional suffixes from path strings, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux Tutorial / Hard Links vs. Symbolic Links in Linux: Differences and Examples

Linux Tutorial / Hard Links vs. Symbolic Links in Linux: Differences and Examples

Compare hard and symbolic links through inode and path behavior, then create both kinds of link and observe what happens when the original name changes.

Linux cat Command: Display and Concatenate File Contents

Linux cat Command: Display and Concatenate File Contents

Learn how to use the Linux cat command to display text files, concatenate multiple files, number lines, reveal hidden characters, and avoid unsafe redirection mistakes.

Linux printenv Command: Print Environment Variable Values

Linux printenv Command: Print Environment Variable Values

Learn how to use the Linux printenv command to print all environment variables or selected variable values, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux apk Command: Manage Packages on Alpine Linux

Linux apk Command: Manage Packages on Alpine Linux

Learn how to manage Packages on Alpine Linux with the Linux apk command, including practical examples, key options, and important precautions.

Linux ip Command: Inspect and Configure Network Interfaces and Routes

Linux ip Command: Inspect and Configure Network Interfaces and Routes

Learn how to inspect and Configure Network Interfaces and Routes with the Linux ip command, including practical examples, key options, and important precautions.