'Node.js: Killing sub processes of ChildProcess#spawn
Consider the following code:
import {spawn, exec} from 'child_process';
var child = spawn('su',
[process.env.USER, '-c', 'while (true); do sleep 0.3; echo "tick"; done'],
{stdio: ['ignore', 'pipe', 'pipe']}
);
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);
setTimeout(() => {
child.kill();
}, 1000);
Here I'm trying to run a particular script which runs some other child process (in that example su
will spawn a bash
process) and closes it all. However, I can't make it work as I expect.
Calling child.kill()
kills just the parent process of su
and not its child bash
.
What can be done to make it work — calling exec(`pkill -TERM -P ${child.pid}`)
instead of child.kill()
? As far as I understand, this will kill the whole process tree with parent child.pid
.
Yet, it has some oddity when combining two methods:
setTimeout(() => {
child.kill();
exec(`pkill -TERM -P ${child.pid}`);
}, 1000);`
This code continues writing tick
into the console even after the process has been killed.
Why is this happening? Can somebody explain, please?
Solution 1:[1]
I was facing the exact problem. I found the solution from How to kill child processes that spawn their own child processes in Node.js.
Here is the working form of your code:
const {spawn, exec} = require('child_process');
var child = spawn('./test.sh',
[],
{stdio: ['ignore', 'pipe', 'pipe'], detached: true} // <---- this
);
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);
setTimeout(() => {
process.kill(-child.pid); // <---- and this
// child.kill();
}, 1000);
When I ran your original code, the terminal prevented me to run su
from script, so I modified the testing code to ./test.sh
, which does the same thing:
(while (true); do sleep 0.3; echo "tick"; done)
So the lines that do the magic are detached:true
and process.kill(-child.pid)
.
Quoted from the original site:
We can start child processes with {detached: true} option so those processes will not be attached to main process but they will go to a new group of processes. Then using process.kill(-pid) method on main process we can kill all processes that are in the same group of a child process with the same pid group.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Richard Wong |