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?
process
is a built-in node module, i.e.const process = require('node:process');
. It is not a spawned process instance. Butprocess
is a special module that is available globally and does not need to be imported. – Soap