Windows 10, kill child process, can't get correct PID - node.js

I use win10 if it's matters, in bash(git)
I have SH script:
start node ./e2e-tests/apimocker_runner.js & pid1=$!
start npm run protractor -- --binaryPath=./build/appInstaller/win-unpacked/ & pid2=$!
sleep 10
kill $pid1
kill $pid2
when i try kill processes by pid i have error:
bash: kill: (6616) - No such process
As i know in $! we have last child process pid, but this don't work.
Cuz then i type in bash:
start bash & pid=$!
echo $pid
$pid === 1000 (for example)
but if i type
echo $$
in created bash by previous command i have another pid
$$ ==== 1200 (for example)
Also I found what if i type start bash this create non-child process, but i want to create child process and wait for them like wait $pid
How i can do this?

A variable set in one bash instance is not visible in another bash instance which is not its child process (and only then if the parent did export variable to expose it to children).

Related

SIGINT in bash script

I have the following bash script.
#!/bin/bash
while :
do
sleep 2
infiniteProgramm -someParametrs
sleep 10
#in this line I need to stop my infiniteProgramm with bash command (SIGINT) (like Ctrl+C, but automatic)
clear
done
How can I send a SIGINT signal to my infiniteProgramm?
First: run infiniteProgram in the background:
infiniteProgram -someParameters &
Second: retrieve its PID from $!.
pid=$!
Third: kill it.
sleep 10
kill -2 $pid
2 corresponds to SIGINT, see kill -l for the list of all the signals.

In Bash, Kill background function will not kill internal process, why they have different pid?

For convenience, I put my server command into a function, but I background the function got a pid is not my server's pid.
myserver(){
# May contain complicate parameter
sleep 10
}
myserver > my.log &
pid=$!
ps aux|grep sleep
echo "Found PID " $pid is different from ps
So, if I kill $pid will not kill real server process(here is sleep).What should I do ?
UPDATE
sleep 10 &
pid=$!
ps aux|grep sleep
echo Found PID $pid is same
UPDATE
In this case
myserver(){
# May contain complicate parameter
sleep 10
}
myserver > my.log &
kill $!
Will kill the sleep process, but actually, my server is java -jar, when I do kill $!, the java process will not get killed.
In order to kill via the kill command you should provide the PID and not the Job Id.
Check this post about JID and PID
Update on Comment:
Are u sre you are providing it right?
In my system:
$ sleep 20 &
[2] 10080
$ kill -9 $!
[2]- Killed sleep 20
$
Folow up
Ok now I get it. Sorry i misinterpretted your question. What you describe is the expected behavior:
$! Expands to the decimal process ID of the most recent background command (see Lists) executed from the current shell. (For example, background commands executed from subshells do not affect the value of "$!" in the current shell environment.) For a pipeline, the process ID is that of the last command in the pipeline.
So in that case maybe try this proposed solution
Update on Question:
Ok, in the case of java proces I would try a regexp:
pkill -f 'java.*<your process name or some -classpath jar or something unique to the process you want to kill>'
In fact, any string or classpath jar that came along with this command and would result to a match would do the job.

Bash script: Kill one process when other completes

I am trying to write a bash script to run one process after another approximately 1024 times with different command line options. However one of the processes include an infinite loop and I am trying to kill that process before another iteration of the loop begins.
So here is what I tried so far (prog1 includes the infinite loop and I want to kill it when papi finishes running) :
#!/bin/bash
for (( i=0; i<32780; i+=32))
do
./prog1 $i &
pid=$!;
sleep 5s
./papi
kill -s 2 $pid
done
However it does not kill any prog1 instances, and of course it continues to create them at the beginning of each iteration. What am I doing wrong?
It kills a process before finishing:
pkill $!
for example:
telnet 192.168.1.1 1>/dev/null 2>&1 &
pkill $!

How to kill a shell script and processes it created?

I run a shell script inside php (using shell_exec). I want to kill it and all processes it created when it is in operation. I know the shell script pid. Do you have any suggestion?
I am using ubuntu, php as apache module.
Thank you.
Example:
#!/bin/bash
echo hello
sleep 20
When I kill my script (shell_exec("sudo kill -9 $pid")), the sleep process is not killed which is not desired.
use
pkill -TERM -P pid
will kill the child processes
see this answer
Use this kill command instead:
kill -- -$pid
to kill the running script and all its spawned children.

Sleep in a while loop gets its own pid

I have a bash script that does some parallel processing in a loop. I don't want the parallel process to spike the CPU, so I use a sleep command. Here's a simplified version.
(while true;do sleep 99999;done)&
So I execute the above line from a bash prompt and get something like:
[1] 12345
Where [1] is the job number and 12345 is the process ID (pid) of the while loop. I do a kill 12345 and get:
[1]+ Terminated ( while true; do
sleep 99999;
done )
It looks like the entire script was terminated. However, I do a ps aux|grep sleep and find the sleep command is still going strong but with its own pid! I can kill the sleep and everything seems fine. However, if I were to kill the sleep first, the while loop starts a new sleep pid. This is such a surprise to me since the sleep is not parallel to the while loop. The loop itself is a single path of execution.
So I have two questions:
Why did the sleep command get its own process ID?
How do I easily kill the while loop and the sleep?
Sleep gets its own PID because it is a process running and just 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 running the loop) of the sleep is.
Because "sleep" is a process, not a build-in function or similar
You could do the following:
(while true;do sleep 99999;done)&
whilepid=$!
kill -- -$whilepid
The above code kills the process group, because the PID is specified as a negative number (e.g. -123 instead of 123). In addition, it uses the variable $!, which stores the PID of the most recently executed process.
Note:
When you execute any process in background on interactive mode (i.e. using the command line prompt) it creates a new process group, which is what is happening to you. That way, it's relatively easy to "kill 'em all", because you just have to kill the whole process group. However, when the same is done within a script, it doesn't create any new group, because all new processes belong to the script PID, even if they are executed in background (jobs control is disabled by default). To enable jobs control in a script, you just have to put the following at the beginning of the script:
#!/bin/bash
set -m
Have you tried doing kill %1, where 1 is the number you get after launching the command in background?
I did it right now after launching (while true;do sleep 99999;done)& and it correctly terminated it.
"ps --ppid" selects all processes with the specified parent pid, eg:
$ (while true;do sleep 99999;done)&
[1] 12345
$ ppid=12345 ; kill -9 $ppid $(ps --ppid $ppid -o pid --no-heading)
You can kill the process group.
To find the process group of your process run:
ps --no-headers -o "%r" -p 15864
Then kill the process group using:
kill -- -[PGID]
You can do it all in one command. Let's try it out:
$ (while true;do sleep 99999;done)&
[1] 16151
$ kill -- -$(ps --no-headers -o "%r" -p 16151)
[1]+ Terminated ( while true; do
sleep 99999;
done )
To kill the while loop and the sleep using $! you can also use a trap signal handler inside the subshell.
(trap 'kill ${!}; exit' TERM; while true; do sleep 99999 & wait ${!}; done)&
kill -TERM ${!}

Resources