Sleep in a loop time gets your pid

I have a bash script that does some parallel processing in a loop. I do not want the parallel process to increase the processor, so I use the sleep command. Here is a simplified version.

  (while true; do sleep 99999; done) &

So, I execute the above line from the bash prompt and get something like: [1] 12345

Where [1] is the job number, and 12345 is the process identifier (pid) of the while loop. I do a kill 12345 and get:

  [1] + Terminated (while true; do
     sleep 99999;
 done)

It seems that the whole script has been interrupted. However, I do ps aux|grep sleep and find that the sleep command is still strong, but has its own pid! I can kill sleep , and everything seems perfect. However, if I were to first kill the sleep, the while loop starts a new sleep pid. This is such a surprise for me, because sleep is not parallel to the while loop. The loop itself is the only execution path.

I have two questions:

  • Why did the sleep command get its own process id?
  • How easy is it to kill a while and sleep loop?
+4
source share
6 answers
  • Sleep gets its own PID because it is a process that is running and waiting. Try which sleep to see where it is.
  • You can use ps -uf to see the process tree on your system. From there, you can determine what the PPID (parent PID) of the shell (the one that runs the loop) means sleep.
+5
source

Have you tried to make kill %1 , where 1 is the number that you get after running the command in the background?

I did it right now after starting up (while true;do sleep 99999;done)& , and it completed it correctly.

+1
source

"ps --ppid" selects all processes with the specified parent pid, for example:

 $ (while true;do sleep 99999;done)& [1] 12345 $ ppid=12345 ; kill -9 $ppid $(ps --ppid $ppid -o pid --no-heading) 
+1
source

You can kill a group of processes.

To find the process group of your process:

 ps --no-headers -o "%r" -p 15864 

Then run the process group using:

 kill -- -[PGID] 

You can do it all in one command. Try:

 $ (while true;do sleep 99999;done)& [1] 16151 $ kill -- -$(ps --no-headers -o "%r" -p 16151) [1]+ Terminated ( while true; do sleep 99999; done ) 
+1
source
  • Because "sleep" is a process, not an inline function or similar

  • You can do the following:

     (while true;do sleep 99999;done)& whilepid=$! kill -- -$whilepid 

The code above kills a group of processes because the PID is given as a negative number (for example, -123 instead of 123). In addition, it uses the $! variable $! where the PID of the most recently executed process is stored.

Note: When you execute a process in the background in interactive mode (i.e. using the command line), it creates a new group of processes, which happens to you. Thus, it is relatively easy to "kill everyone" because you just need to kill the entire group of processes. However, when the same thing is done in the script, it does not create any new group, because all new processes belong to the script identifier, even if they are running in the background (task management is disabled by default). To enable job management in a script, you just need to put the script at the beginning:

following:
 #!/bin/bash set -m 
+1
source

To kill the while and sleep while with $! , you can also use the trap signal handler inside the subshell.

 (trap 'kill ${!}; exit' TERM; while true; do sleep 99999 & wait ${!}; done)& kill -TERM ${!} 
0
source

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


All Articles