> ## 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.

# Bash Process Group

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.

```bash theme={"dark"}

# 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:

```bash theme={"dark"}
$ 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.

```bash theme={"dark"}

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

# Note the negative sign before the PGID
kill -TERM -45101
```

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor Bash Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
