I basically want to run a script (which calls more scripts) in a new process group so that I can send signal to all the processes called by the script.
In Linux, I found out setsid helps me in doing that, but this is not available on FreeBSD.
Syntax for setsid (provided by util-linux-ng).
setsid /path/to/myscript
I, however learnt that session and process group are not the same. But starting a new session also solves my problem.
Sessions and groups are not the same thing. Let's make things clean:
A session consists of one or more process groups, and can have a controlling terminal. When the session has a controlling terminal, the session has, at any moment, exactly one foreground process group and one or more background process groups. In such a scenario, all terminal-generated signals and input is seen by every process in the foreground process group.
Also, when a session has a controlling terminal, the shell process is usually the session leader, dictating which process group is the foreground process group (implicitly making the other groups background process groups). Processes in a group are usually put there by a linear pipeline. For example,
ls -l | grep a | sort
will typically create a new process group wherels
,grep
andsort
live.Shells that support job control (which also requires support by the kernel and the terminal driver), as in the case of bash, create a new process group for each command invoked -- and if you invoke it to run in the background (with the
&
notation), that process group is not given the control of the terminal, and the shell makes it a background process group (and the foreground process group remains the shell).So, as you can see, you almost certainly don't want to create a session in this case. A typical situation where you'd want to create a session is if you were daemonizing a process, but other than that, there is usually not much use in creating a new session.
You can run the script as a background job, as I mentioned, this will create a new process group. Since
fork()
inherits the process group ID, every process executed by the script will be in the same group. For example, consider this simple script:This prints something like:
As you can see,
execute.sh
,ps
andgrep
are all on the same process group (the value inPGID
).So all you want is:
Then you can check the process group ID of
myscript
withps -o pid,ppid,pgid,comm | grep myscript
. To send a signal to the group, usekill
with the negative of the process group ID (PGID
is thePID
of the leader of the group). A signal sent to a group is delivered to every process in that group. In the above example, to sendSIGTERM
to every process started byexecute.sh
, including the script itself, you would usekill -- -12343
. (Note that sending a signal to the whole group is different from sending a signal to just the group leader:kill 12343
andkill -- -12343
are different!)