Shell – How to move a process from one process group to another, and how to list the processes in each process group

processprocess-groupsshell

Based on what I have learned so far, a terminal has only one session, and a session has one or more process groups, and a process group has one or more processes.

The following image illustrates this:

enter image description here

I have two questions:

  1. How to move a process from one process group to another?
  2. How to list the processes in each process group?

Edit: I mean how to do these two things from the terminal and not programmatically.

Best Answer

From a user's or even a typical programmer's perspective, you don't move processes from one group to another. Organizing process groups is the job of the shell. When you run a job interactively, the shell puts it in its own group. The primary intent of doing that is to kill the whole group (e.g. all the processes in a pipeline) when the user presses Ctrl+C.

More generally, the one thing that is made possible by process groups is to atomically kill a set of processes. If you try to list some processes and then kill them, one of them may have forked in between. When you kill a process group, that kills all the processes in the group, even if they're busy forking.

The one thing you may sometimes want to do as a user or application programmer is to run a new process in its own group. There's no user-level command to do just that. You can do it by starting an interactive shell. (See Timing out in a shell script for a complex example.) There are other commands such as the timeout utility from GNU coreutils and the Linux and the setsid utility from the util-linux suite that create a new process group as part of their oepration.

The system call to move a process to a different process group is setpgid. (There's also a partial alias called setpgrp.) There are restrictions: it may only be called by the process itself or its parent, and the target group must be in the same session as the original group. You can't arbitrarily move a process from one group to another.

There's no specific way to enumerate the processes in a group. All you can do is enumerate all the processes and select the ones in that specific group. You can list process groups in the ps output by including the pgid column (e.g. ps -e -o pid,ppid,pgid,args).