Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A process group is an OS-level abstraction used by Bash to manage a collection of one or more related processes as a single unit, primarily for job control and signal distribution. Every process belongs to exactly one process group, identified by a Process Group ID (PGID).

Process Group Leader

The first process created in a process group is designated as the process group leader. The PGID of the group is strictly equal to the Process ID (PID) of the process group leader. The process group continues to exist as long as at least one process remains in the group, even if the process group leader terminates.

Pipeline Grouping

Bash’s handling of process groups for pipelines depends strictly on whether job control is enabled.
  • Job Control Enabled: In interactive shells (the default) or when explicitly enabled via set -m, Bash forks the necessary child processes and places all constituent commands of a pipeline into a single, newly created process group.
  • Job Control Disabled: In non-interactive scripts (the default), Bash does not create a new process group for pipelines. Instead, all processes in the pipeline inherit the shell’s existing process group.

# When job control is enabled, all three processes are placed into a new process group
command1 | command2 | command3
To visualize process groups, you can use the ps command with custom output flags to expose the PID and PGID. To prevent the output from including the shell and the ps command itself, the target PIDs must be explicitly filtered:
$ sleep 100 | cat | grep foo &
[1] 45103


# Filtering ps output by the specific PIDs of the pipeline
$ ps -p 45101,45102,45103 -o pid,pgid,cmd
  PID  PGID CMD
45101 45101 sleep 100      # Process Group Leader (PID == PGID)
45102 45101 cat            # Shares PGID 45101
45103 45101 grep foo       # Shares PGID 45101

Terminal and Signal Mechanics

Bash interacts with the kernel’s terminal driver (TTY) to manage process states. A session can have multiple process groups, but only one foreground process group per controlling terminal at any given time. All other process groups in the session are background process groups.
  • Signal Propagation: When a terminal-generated signal is triggered (e.g., SIGINT via Ctrl+C, SIGQUIT via Ctrl+\, or SIGTSTP via Ctrl+Z), the kernel delivers the signal to every process within the foreground process group simultaneously.
  • Terminal I/O: Only the foreground process group is permitted to read from the controlling terminal. If a process in a background process group attempts to read from the terminal, the kernel suspends the entire process group by sending it a SIGTTIN signal. Depending on the terminal’s tostop flag, writing to the terminal from a background process group may similarly trigger a SIGTTOU signal.

POSIX System Calls

Under the hood, Bash manages process groups using specific POSIX system calls:
  • setpgid(pid, pgid): Assigns a process to a process group. Bash calls this after forking but before executing the command.
  • tcsetpgrp(fd, pgid): Instructs the terminal driver to make the specified process group the foreground process group.
  • kill(-pgid, signal): Sends a signal to all processes in a process group. The negative sign preceding the PGID differentiates it from a standard PID.

# Sending SIGTERM to an entire process group via the kill command

# Note the negative sign before the PGID
kill -TERM -45101
Master Bash with Deep Grasping Methodology!Learn More