Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

starting a new process group from bash script

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.

like image 983
Thirupathi Thangavel Avatar asked Dec 03 '22 16:12

Thirupathi Thangavel


1 Answers

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 where ls, grep and sort 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:

#!/bin/bash

ps -o pid,ppid,pgid,comm | grep ".*"

This prints something like:

  PID  PPID  PGID COMMAND
11888 11885 11888 bash
12343 11888 12343 execute.sh
12344 12343 12343 ps
12345 12343 12343 grep

As you can see, execute.sh, ps and grep are all on the same process group (the value in PGID).

So all you want is:

/path/to/myscript &

Then you can check the process group ID of myscript with ps -o pid,ppid,pgid,comm | grep myscript. To send a signal to the group, send it to the group leader (PGID is the PID of the leader of the group). A signal sent to a group is delivered to every process in that group.

like image 109
Filipe Gonçalves Avatar answered Dec 22 '22 11:12

Filipe Gonçalves