Shell – Does bash support forking similar to C’s fork()

forkshell

I have a script that I would like to fork at one point so two copies of the same script are running.

For example, I would like the following bash script to exist:

echo $$
do_fork()
echo $$

If this bash script truly existed, the expected output would be:

<ProcessA PID>
<ProcessB PID>
<ProcessA PID>

or

<ProcessA PID>
<ProcessA PID>
<ProcessB PID>

Is there something that I can put in place of "do_fork()" to get this kind of output, or to cause the bash script to do a C-like fork?

Best Answer

Yes. Forking is spelled &:

echo child & echo parent

What may be confusing you is that $$ is not the PID of the shell process, it's the PID of the original shell process. The point of making it this way is that $$ is a unique identifier for a particular instance of the shell script: it doesn't change during the script's execution, and it's different from $$ in any other concurrently running script. One way to get the shell process's actual PID is sh -c 'echo $PPID'.

The control flow in the shell isn't the same as C. If in C you'd write

first(); fork(); second(); third();

then a shell equivalent is

after_fork () { second; third; }
first; after_fork & after_fork

The simple shell form first; child & parent corresponds to the usual C idiom

first(); if (fork()) parent(); else child();

& and $$ exist and behave this way in every Bourne-style shell and in (t)csh. $PPID didn't exist in the orignal Bourne shell but is in POSIX (so it's in ash, bash, ksh, zsh, …).