It's one of a number of special shell variables. From the POSIX standard relating to this:
$
Expands to the decimal process ID of the invoked shell. In a subshell (see Shell Execution Environment), $
shall expand to the same value as that of the current shell.
Other special shell variables include !
(the PID of the most recently started background task), ?
(the exit status of the most recent task terminating), #
(the number of positional parameters), *
(the positional parameters, concatenated into a single string), @
(the positional parameters, as a list), -
(the current shell options), and 0
(zero; the name of the shell or script).
Also, from the bash
manual's "Special Parameters" section:
$
Expands to the process ID of the shell. In a ()
subshell, it
expands to the process ID of the current shell, not the
subshell.
Other shells will have a similar wording in their manuals.
In short, the $
variable, whose value you get by typing $$
, holds the process ID (PID) of the current shell process.
You can double-check this like so:
% echo "$$"
85776
% ps -p "$$"
PID TT STAT TIME COMMAND
85776 p1 SN 0:00.19 -zsh (zsh)
This shows that $$
expands to 85776 for my particular shell process, and that this PID does indeed correspond to a zsh
login shell, which is what I'm using.
$$
and others like it aren't technically variables, just parameters, the distinction being a bit of hair-splitting. "Variables" are parameters with alphanumerical names (not starting with digits), and only variables can be set with e.g.var=value
. Also,$foo
is parameter expansion: it can be used with non-variable parameters too. Though in practice people of course use "variable expansion" to mean the same thing, and e.g. Bash's manual uses the phrase "parameter and variable expansion". – ilkkachu Apr 18 '21 at 12:58