Killing a bash script does not kill child processes

I wrote a test script that runs another script to start the server for testing. When the tests are completed, the SIGKILL message is sent to the server process, however, when testing the script again, the server generates an EADDRINUSE error (I'm in node.js environment), which means that the port the server is trying to connect to. The process we tried to kill with SIGKILL still works. I don't think this is a specific node problem, but rather the lack of education in my way for bash processes to work.

Here are some features, this is my start script called scripts/start-node.sh :

 #!/bin/bash node_modules/.bin/babel-node --stage 0 index.js 

This is my node server called index.js (I did not create any process event listeners):

 Http.createServer(…).listen(PORT, () => console.log(`Server listening on ${PORT}`)) 

And the script launch is controlled by the node child_process module:

 var child = child_process.spawn('scripts/start-node.sh') // Later… child.kill('SIGKILL') 
+9
bash process sigkill child-process
source share
4 answers

To kill a child process and all its children, you can use process.kill with a negative pid (to kill a group of processes)

 var child = child_process.spawn('scripts/start-node.sh', {detached: true}) // Later… process.kill(-child.pid, 'SIGKILL'); 

Read more on the child_process documentation for options.detached

In the case of non-Windows, if the selected option is set, the child process will become the leader of the new process group and session.

Link to the man 2 kill for some details:

If pid is less than -1, then sig is sent to each process in the process group whose identifier is -p.


Another option could use trap in your shell script to intercept the signal and kill all the children and use child.kill('SIGTERM') from node (since SIGKILL will not be intercepted by trap )

 #!/bin/bash trap 'kill $(jobs -p)' EXIT node_modules/.bin/babel-node --stage 0 index.js 
+11
source share

have a process signal handler on your server

server.js

  var http = require('http'); function handleRequest(request, response){ response.end("Hello"); } var server = http.createServer(handleRequest); server.listen(3000, function(){console.log("listening...")}); process.title="testserver" process.on('SIGQUIT', function() { server.close() }); 

startup.sh

  #!/bin/bash node server.js & echo "started" 

and then "shutdown.sh".

shutdown.sh

 #!/bin/bash pkill -QUIT testserver & echo "stoped" 

It will kill all processes with this name if you create multiprocessor processes in your "start-node.sh". That way you can have some cleanup code when shutting down, for example. closing all connections, etc.

and in your test runner you can do

 var exec = require('child_process').exec; exec("./start.sh") // later... exec("./stop.sh") 
0
source share

Just:

 #!/bin/bash if pgrep -x "node" > /dev/null then mv -f /usr/local/bin/node /usr/local/bin/node.1 killall node mv -f /usr/local/bin/node.1 /usr/local/bin/node which node else echo "process node not exists" fi 
0
source share

Do you have output 0 in a script?

Example:

  #!/bin/bash ifconfig exit 0 
-one
source share

All Articles