4

I would like to start a bash script from another bash script, but start it in its own process group just like when you run it from the terminal.

There are a few similar questions, but I can't find an answer that matches my example.

Take these two scripts

$ cat main.sh 
#! /usr/bin/env bash

set -e

echo if this has been started in its own group the following will pass
ps -o ppid,pgid,command $$
ps -o pgid | grep $$
echo passed

$ cat wrapper.sh 
#! /usr/bin/env bash

set -e

./main.sh

When I run main.sh on its own, the terminal puts it in its own group:

$ ./main.sh 
if this has been started in its own group the following will pass
 PPID  PGID COMMAND
20553  1276 bash ./main.sh
 1276
 1276
 1276
passed
$ echo $?
0

but when I run main.sh from wrapper.sh my test fails (as expected)

$ ./wrapper.sh 
if this has been started in its own group the following will pass
 PPID  PGID COMMAND
 2224  2224 bash ./main.sh
$ echo $?
1

But what do I have to put into either wrapper.sh or main.sh to make it run main.sh in its own group the same way it would if it does when it is run straight from the terminal?

(If it makes a difference, I am actually hoping to run ./main.sh & in wrapper.sh but it was easier to run it in the foreground for this experiment.)

(I am using ubuntu 18)

4
  • 2
    Use set -m in wrapper.sh. But the real Q is why you need to run it in a separate process group -- keep in mind that neither session (sid) not process groups/jobs (pgid) work as process containers.
    – mosvy
    Jul 12, 2019 at 12:25
  • 1
    i want to simulate what control-c will do by sending SIGINT to the group
    – Alex028502
    Jul 12, 2019 at 12:33
  • That seems to work. Would you mind turning that into an official answer?
    – Alex028502
    Jul 12, 2019 at 13:47
  • 1
    There are many pitfalls with using monitor mode from a script. For instance, in bash -ic 'set -m; cat &', the cat will get an EIO error instead of being stopped by a SIGTTIN signal when trying to read from the controlling tty. I don't feel like making a list of all the problems related to that. But you can answer your own Q with a practical example of whatever worked for you ;-)
    – mosvy
    Jul 12, 2019 at 14:24

2 Answers 2

1

Assuming Bash, the immediate answer would be to enable "monitor mode" (job control) with set -m, or -m on the command line:

From the man page:

-m Monitor mode. Job control is enabled. This option is on by default for interactive shells on systems that support it (see JOB CONTROL above). All processes run in a separate process group. When a background job completes, the shell prints a line containing its exit status.

$ bash -m wrapper.sh 
if this has been started in its own group the following will pass
 PPID  PGID COMMAND
12630 12631 bash ./main.sh
12631
12631
12631
passed

However, the question is rather tight on the "why", and there might be reasons monitor mode is disabled by default in non-interactive shells, so YMMV.

1
  • 1
    @rescdsk, d'oh. thanks.
    – ilkkachu
    Oct 8, 2021 at 22:15
0

Look into using setsid. It creates a new session for your process, which makes it the process group leader.

See man 1 setsid and man 2 setsid.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.