Re: Our /bin/sh and process group IDs

From: Bryan Drewery <bdrewery_at_FreeBSD.org>
Date: Fri, 25 Mar 2022 19:13:27 UTC
On 3/24/2022 10:13 AM, Ganael Laplanche wrote:
> Hello,
> 
> I am trying to fork a sub-shell with its own process group id through a 
> function that must itself be executed in the background.
> 
> It should work with the following code:
> 
> #----
> #!/bin/sh
> 
> # Parent shell IDs
> ps -o pid,ppid,pgid,comm -p $$
> 
> test_func () {
>    set -m
>    { /bin/sh -c 'sleep 1' ; } &
>    # Forked shell IDs (pgid should be different from parent,
>    # but it is not)
>    ps -o pid,ppid,pgid,comm -p $!

set -m needs to be set from the parent process, not child. In this 
example test_func is a child *and* the sleep is a child which is also 
very racy. Here's a pattern I use that works:

#! /bin/sh

ps -o pid,ppid,pgid,comm -p $$

test_func() {
         mypid=$(sh -c 'echo $PPID')
         ps -o pid,ppid,pgid,comm -p $mypid
}

spawn() {
         local - # cause -m to revert back on return
         set -m
         "$@" &
}

spawn test_func
ps -o pid,ppid,pgid,comm -p $!


> }
> 
> # The following does not work:
> test_func &
> # ...but it works when function is not executed in the background:
> #test_func
> 
> sleep 2
> exit 0
> #----
> 
> Unfortunately, with our /bin/sh, the sleeping process gets the *same* 
> process group ID as its parent.
> 
> I've tested several shell implementations; it works with :
> 
> /usr/local/bin/bash --posix 'test.sh'     # from bash-5.1.16
> /usr/local/bin/zsh --emulate sh 'test.sh' # from zsh-5.8.1
> /usr/local/bin/ksh93 'test.sh'            # from ksh93-devel-2020.06.30
> /usr/local/bin/mksh 'test.sh'             # from mksh-59c
> /usr/local/bin/ksh 'test.sh'              # from pdksh-5.2.14p2_6
> 
> but not with :
> 
> /bin/sh 'test.sh'                         # on 13.0-RELEASE-p8
> /usr/local/bin/dash 'test.sh'             # from dash-0.5.11.5
> 
> am I missing something ?
> 
> Any help welcome :)
> 
> Best regards,
> 


-- 
Bryan Drewery