I have written a test script which runs another script to start the server to test. When the tests have completed a SIGKILL
message is sent to the server process, however when running the test script again the server throws a EADDRINUSE
error (I‘m in a node.js environment) which means the port the server is trying to mount to is currently in use. The process we tried to kill with a SIGKILL
is still running. I don‘t believe this is a node specific issue, but rather a lack of education on my end for how bash processes work.
Here are some specifics, 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 haven‘t authored any process
event listeners):
Http.createServer(…).listen(PORT, () => console.log(`Server listening on ${PORT}`))
And the start script is controlled with the node child_process
module:
var child = child_process.spawn('scripts/start-node.sh')
// Later…
child.kill('SIGKILL')
To kill a child process and all it's children you may use process.kill
with a negative pid
(to kill a process group)
var child = child_process.spawn('scripts/start-node.sh', {detached: true})
// Later…
process.kill(-child.pid, 'SIGKILL');
See details on child_process
documentation for options.detached
On non-Windows, if the detached option is set, the child process will be made the leader of a new process group and session.
Referencing here a portion of man 2 kill
for some details:
If pid is less than -1, then sig is sent to every process in the process group whose ID is -pid.
Another option may be using trap
in your shell script to intercept a signal and kill all the children and using child.kill('SIGTERM')
from node
(as SIGKILL
will not be intercepted by trap
)
#!/bin/bash
trap 'kill $(jobs -p)' EXIT
node_modules/.bin/babel-node --stage 0 index.js