Manipulating processes in Linux is a big part of an admin's job. There are any number of processes that need to be managed. Most of the time, you don't need to manually kill processes. But if you have to, you can get their process number and terminate them with the "kill" command. However, did you know that you can also group processes together and unite them under a single "process group"? And once you have the handle to that group, you can manipulate them as a whole and kill them all at the same time.
Parent Processes and Child Processes and Group IDs
When a process creates a child process, the child is assigned the "PPID" of the parent's process ID. For example, I have two scripts in my directory which call the "sleep" command. Here's what happens when I run one of them and then check the output with the ps command:
ps -e -o pid,ppid,pgid,command
In this, the script "firstcommand" is assigned a process ID of 19639. The "sleep" command that it invokes has a different ID, but the parent ID is also 19639. This is because it was started from within "firstcommand". Also, the "process ID" or PGID is 19639 for both these commands.
So we already have a process ID. Keep in mind that if you exit your shell and come back, these processes will be terminated. To preserve them, we need to start a new session.
Using the "setsid" Command to Start a New Session
The tool we're going to use to create a new process group is called "setsid". It not only creates a separate group, but also starts the commands in a new session altogether. What is a "session"? A session is a collection of process groups, and usually refers to a shell session. The "setsid" command allows us to create commands that will keep running even after you logout. To do this, just run setsid and follow it with the command like this:
And here's the "ps" output:
So we have a new process ID "19652", started with the parent process "1". This is the first process that started during boot - usually init. So when we exit our shell, it doesn't matter and our script continues running. To test this out, I log out of my shell and log back in. Sure enough, the processes are still running:
Everything is the same. The process ID is the same, and it's the same group.
Killing all Processes within a Process Group
You might think that killing the parent process automatically kills all its children. But not necessarily. In fact, the process group will continue to exist even when the process that started it has died even though the process group ID (pgid) and process ID (pid) are the same. So the pgid can survive when the pid dies. To kill a process group and all its children and subchildren, use the following command:
kill -TERM -[pgid]
Replace [pgid] with the process group ID. Note that it looks as if we're sending a signal to the negative of the process ID!
Starting Multiple Commands within the same Process Group and Session
Let's say we have two commands instead of one that we want to bunch together into a process group. In my example, I'm going to use both my scripts "firstcommand" and "secondcommand". Like this:
setsid sh -c './firstcommand & ./secondcommand'
Here, I use setsid to create a new non-interactive shell session with the two commands. This gives me the following "ps" output:
Here, you can see that "firstcommand" and "secondcommand", along with their associated "sleep" processes, all share the same process group ID. You can chain as many commands together like this as you want separated with ampersand (&) symbols. And you can kill them all at the same time using the -TERM signal I showed you earlier.
This is a neat way to manage associated processes that you want to keep track of together. Using grep, you can view all of them at the same time and keep track of their resource usage together, and if necessary, terminate them all at once!