$$ and $! help you manage process IDs (PIDs) for debugging, automation, and scripting tasks. While they might not pop up every day, knowing how to use them can streamline background jobs, service management, and process monitoring.
Before diving into these variables, let’s clarify how TTYs, shells, and PIDs relate:
- When you open a terminal, it’s assigned a TTY (teletype) name.
- A shell (e.g., Bash) runs on that TTY and acts as the parent process.
- Any command or script executed in that shell becomes a child process.
- Every process—from parent shells to background jobs—has a PID and a lifecycle (start → run → exit).
Table of Special PID Variables
| Variable | Description | Typical Use Case |
|---|---|---|
$! | PID of the most recently launched background job | Tracking & controlling background tasks |
$$ | PID of the current shell or shell-script process | Self-awareness in scripts |
Using $! to Capture Background Job PIDs
The $! variable returns the PID of the last job you sent to the background.
$! holds the PID until you start another background job:
Storing $! in a Bash Script
A common pattern is launching a service in the background, capturing its PID, and later terminating it. For example, starting an Apache JMeter server:
Using $$ to Identify Your Shell or Script
The $$ variable prints the PID of the current shell or script process:
$$ value:
Inspecting $$ Inside a Script
Create print_pid.sh:
- PID 94479 corresponds to the script itself (
$$). - PID 94481 is the child
sleepprocess.
$$ and Subshell Behavior
Subshells inherit the parent shell’s PID, so $$ stays constant:
$$ show the same PID because subshells share the parent’s process ID.
Key Takeaways
$!returns the PID of the last command run in the background.$$returns the PID of your current shell or the running script.