Preventing propagation of SIGINT to Parent Process - Problem with the child

Context :
From a script which call a script … which call the nvidia driver script, the nvidia proprietary driver script freeze when using command uninstall ( there was nothing to uninstall).
The return key in response to the ‘ok screen’ for leaving does not work.
The problem is that CTRL-C abort my long script.

I started with this which works.
Sample : https://unix.stackexchange.com/questions/80975/preventing-propagation-of-sigint-to-parent-process

Example:
  


  - the Parent script:
  #!/bin/sh

trap 'echo "PARENT: caught SIGINT; exiting"; exit 1' INT

echo "PARENT: pid=$$"
echo "PARENT: Spawning child..."
./Child
echo "PARENT: child returned"
echo "PARENT: exiting normally" 
  - the Child script:
#!/bin/sh -m
#         ^^        
# notice the -m option above!

trap 'echo "CHILD: caught SIGINT; exiting"; exit 1' INT

echo "CHILD: pid=$$"
echo "CHILD: hit enter to exit"
read foo
echo "CHILD: exiting normally" 



But in the child if I change

    read foo

by

    
   while true ; do
       echo "sleeping"
       sleep 2 
    done

that does not work anymore.

PS : this work also

    
while sleep 2 ; do
    echo "sleeping"
done

Any help is welcome about this behaviour.

Not exactly the answer you’re looking for, but the parent process is exiting its own process because it’s telling it to do so. You can choose to do anything else instead, including nothing at all.

Isn’t your answer in the last answers in your Stackexchange reference?
The preferred answer doesn’t provide the reasoning but is in the bottom two non-preferred answers… The SIGINT is sent to the foreground process group which includes Parent and Child processes.

Then a couple suggestions were made to run the two scripts in separate process groups or modify the Parent to handle the SIGINT differently than default.

TSU

If i have understood the explanation in the examples, -m in the child’s shebang prevent the parent to exit.

But my question is not on this part ( if one consider that I have understood the explanation :wink: )
My question is why :


while true ; do
    echo "sleeping"
    sleep 2
done

CTL-C is not stoping the child
but

while sleep 2 ; do
    echo "sleeping"
done

CTL-C is stoping the child

Any help is welcome

One of the suggested solutions, reworded…

Don’t make the 2 scripts Parent and Child.
Call the “Child” as its own, independent script.
ergo… No relationship, no “propagation” between the scripts.

Else,
The other suggestion is more complicated, writing error handling code to avoid the default behavior.

TSU

That does not answer the question at post #4
Anyway Thank you for helping

If “child” means “sleep 2” - of course ^C stops it and then it is restarted.

while sleep 2 ; do
    echo "sleeping"
done

CTL-C is stoping the child

If “child” means “echo sleeping” - it is near to impossible for ^C to hit it, it executes too fast. You again are stopping “sleep 2” which terminates loop (look at exit code of “sleep 10” interrupted by ^C).

Thank you for taking care of my question.
I rephrase my question.
In post #4 I said :
a script named parent.sh for example call a script named child.sh
“-m” in the child’s shebang prevent the parent to exit; that seems to be correct.
Now the child’s script contains :

while true ; do
    echo "sleeping"
    sleep 2
done

In that case each time I type CTRL-C, I see on the screen :

sleeping
sleeping
^Csleeping
sleeping
sleeping
sleeping
^Csleeping
sleeping

Now the child’s script contains :

while sleep 2 ; do
    echo "sleeping"
done

In that case each time I type CTRL-C, the program stop and I see on the screen :

sleeping
sleeping
sleeping
^C

So why is there a different behaviour.
In the first case “^C” is printed to the screen, so I suppose it has been detected.

What exactly you do not understand in “in the first case loop continues and in the second case loop terminates”? In the first case you kill program in loop body and in the second case you kill program in loop condition.

Actually this seems to be bash-specific and starting with 5.0 bash changed behavior to pretend it also received SIGINT if child received SIGINT. By default it terminates bash. Out of curiosity I checked two shells that were installed besides bash here - mksh and dash. mksh runs both bash process and sleep in the same process group (even though it has -m option), so shell simply gets SIGINT when ^C is pressed. dash runs sleep in different process group so only sleep is killed by ^C but dash sends itself SIGINT in this case and so also terminates.

Too sophisticated for me. It is far from my knowledge.
Any way thank you for taking care of my questions.