How to make processes using & (in bash) and kill them?

I have a script that runs another script in the background and then terminates it. I expected the child script to disappear, but in the end, it still manages to print some result. Here is an example:

in script one.sh:

echo "this is one" ./two.sh & sleep 1 pid=$! kill $pid echo "this was one" 

in script two.sh:

 echo "this is two" ./three.sh echo "this was two" 

in script three.sh:

 echo "this is three" sleep 5 echo "this was three" 

I ran. /one.sh, which should run two.sh in the background, which in turn starts three.sh, but not in the background! Output: get:

 this is one this is two this is three this was one this was three 

Should "this was three" not be displayed in the output file, since three.sh did not start in the background, and two.sh was interrupted by one.sh? Could you also point me to any documentation that describes how processes behave when (not) in the background and what happens when they end?

Many thanks for your help!

+4
source share
3 answers

You kill the background process two.sh , but not two.sh and its child three.sh .

This question:

The best way to kill all child processes

more information on killing child processes.

+1
source

When you start a new process with a bash script, this is basically done by fork ().

The new process, called the child, is an exact duplicate of the calling process, called the parent (with the exception of a few points that can be found in the man-fork).

If the parent dies, the child becomes a child of the init process. Then the role of the init process is to collect the child's return code (reap) after it exits. Therefore, when you kill two, the three do not kill, but simply get another parent. And that is the reason for the three laggards.

The question is discussed from the C-point of view here: How to make the child process die after exiting the parent?

+1
source

The reason for this may seem to be that the TERM signal (by default, from "kill") will be propagated to child processes, in other words, that the SIGTERM signal (signal No. 15) received by two.sh will also propagate to three.sh . However, this is actually not the case. Killing two.sh simply removes tr.sh to start the init process (proceess ID 1) as the new parent process, and init will be cleared after three .sh when it exits.

The situation is complicated with process groups, and the bash documentation tells how the signals generated by the keyboard are sent to all processes in the foreground process group, often the pipeline runs without "&". in the end. However, these problems do not apply to example scenarios.

Note. On Unix, you should not use .sh extensions for executable scripts. Focus on the right choice of "#! / Bin / bash" or "#! / Bin / sh" in the first line. Teams should not expose their implementation language in the team name, so as not to switch to another language later when the implementation language changes, but another code has returned to the original, now incorrect extension.

0
source

Source: https://habr.com/ru/post/1488711/


All Articles