How do you get the PID in bash? |
January 27th, 2014 |
bash, tech |
bash
someone will tell you:
The variable $$
contains the PID.
This is usually correct, but not always. Sometimes it can be
incorrect, but in a way that's actually closer to what you wanted.
The basic problem is that many bash
constructs run in a
subshell. This means the shell will fork itself, running your
function in a separate process. This allows simple concurrency, but
it also means a new process id. For example:
$ function a { echo $$; } $ function b { echo $BASHPID; }Function
a
uses $$
while b
uses
$BASHPID
. When run as normal functions they both give the PID
of bash
running them:
$ a 6042 $ b 6042When run in the background, however, they diverge:
$ a & 6042 $ b & 14774To run a function in the background
bash
uses a multiprocess
model, fork
ing a subshell for each one, so we should expect
both a &
and b &
to give new PIDs. In order to make
this process faster, though, and because POSIX says
so, bash
doesn't reinitialize itself when creating a
subshell. This means $$
, which was computed once when
bash
started, continues to have its original value.
$BASHPID
always
looks up the current PID of the executing process, however, so it does
change when you make a subshell.
While this definition of $$
is frustrating if you actually
want to get the current process id, for example to let each background
function have free reign of /tmp/PID
, in many cases this
definition is actually helpful. There are many simple constructs in
bash
that require subshells, and it's convenient that
$$
stays consistent. For example:
$ ls $SOME_PLACE | while read fname ; do some_command $fname >> /tmp/$$.output done $ other_command /tmp/$$.outputBecause pipes run in a subshell if
$$
were defined like
$BASHPID
all of these some_command
outputs would
build up in some random file in /tmp
and
other_command
would look in a different file. Instead
$$
happens to mean the right thing, and everything works.
Comment via: google plus, facebook