I'm spawning a child process using Node 6.9.
const child = require('child_process').execFile('command', args);
child.stdout.on('data', (data) => {
console.log('child:', data);
});
child.stderr.on('data', (data) => {
console.log('child:', data);
});
child.on('close', (code, signal) => {
console.log(`ERROR: child terminated. Exit code: ${code}, signal: ${signal}`);
});
My child process runs for ~1m 30s but then I get this output from my Node.js program:
ERROR: child terminated. Exit code: null, signal: SIGTERM
What terminates my child process and why?
Edit:
I've added killSignal: 'SIGILL' as an option.
var child = require('child_process').execFile('geth', args, { killSignal: 'SIGILL'});
Now, I get this:
ERROR: go-ethereum terminated. Exit code: 2, signal: null
I found the problem and a solution.
From https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_child_process_execfile_file_args_options_callback
maxBuffer largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed (Default: 200*1024)
I can set the maxBuffer option higher.
childProcess.execFile('geth', args, { maxBuffer: 400 * 1024});
It seems you can't disable the maxBuffer option, not even by setting it to 0. But it seems to be on purpose.
Related
Following is my gulp task:
httpServer.on("close", (code, signal) => {
console.log(
`child process terminated due to receipt of signal ${signal}, code ${code}`
);
console.log("httpServer close");
resolve();
})
);
await new Promise((resolve) => setTimeout(resolve, 2e3));
httpServer.kill("SIGINT");
await httpServerClose;
console.log("here");
I got following output:
Available on:
http://127.0.0.1:5001
http://192.168.31.122:5001
http://172.21.96.1:5001
http://172.18.192.1:5001
Hit CTRL-C to stop the server
child process terminated due to receipt of signal SIGINT, code null
httpServer close
here
[13:32:57] Finished 'build:release' after 2.01 s
The problem is port 5001 is still in use.
I'm on windows 10, node v16.13.1
.kill() doesn't guarantees that the process will successfully terminate. You may check for the resulting boolean that kill() returns, but that only indicates wheter the signal was delivered or not.
childProcess.on('close', (code, signal) => {
console.log(
`child process terminated due to receipt of signal ${signal}`);
});
// Send SIGHUP to process.
const signalDelivered = childProcess.kill('SIGHUP');
console.log(signalDelivered)
For some reason, the childProcess is still running / crashed or the SIGINT was not handled correctly.
My suggestion is that you implement "Graceful shutdown".
Remember, if in your childProcess code you are handling process.on('SIGINT', ..),you need to close the server that is listening connections and then call process.exit(0).
const server = app.listen(5001)
process.on('SIGINT',function(){
server.close(err => {
//exit after server is not listening anymore
process.exit(err ? 1 : 0)
})
});
I am trying to kill a previously forked child process in Node.js. I'm unsure if it's working because my console.log line is not being hit in the child process.
Here is what I'm calling from the parent:
console.log("sending SIGINT from main");
child.kill("SIGINT");
And in the child:
process.on("SIGINT", () => {
console.log("Killing bot");
DBS.Bot.destroy();
process.exit();
});
The only console log I see is from the parent.
When spawning a NodeJS child process, this child process' stdout is not the same as the parent process' stdout stream, which is why you do not see any logging output. You can add the following code to copy any output of your child process to your main process' stdout stream:
child.stdout.on ("data", (data) => {
console.log ("child process: " + data.toString ());
});
In some circumstances, it can be useful to also capture stderr output, which is the stream NodeJS' console.err () writes to:
child.stderr.on ("data", (data) => {
console.log ("child process error: " + data.toString ());
});
Also, to make sure a child process has exited with a non-error code, i.e. the exit code is 0, you can use NodeJS' child_process "exit" signal:
child.on ("exit", (code, signal) => {
if (signal !== null) console.log ("child exited due to signal '" + signal + "'");
else console.log ("child exited with code " + code);
});
For more information, make sure to check out NodeJS' documenation on child_process.
Additionally, how to spawn a child process that ignore SIGTERM and can only be killed by SIGKILL?
Because this option is associated with the timeout option.
In spawn you have to decide when you kill the process.
Example: (from doc)
const { spawn } = require('child_process');
const grep = spawn('grep', ['ssh']);
grep.on('close', (code, signal) => {
console.log(
`child process terminated due to receipt of signal ${signal}`);
});
// Send SIGHUP to process
grep.kill('SIGHUP');
I am trying to kill a process using the kill method in child_process. But I get the following error as I try to call the function:
TypeError [ERR_UNKNOWN_SIGNAL]: Unknown signal: 18408
I am doing as follows:
const ls = spawn('node',['print']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
setTimeout(() => {
ls.kill(ls.pid);
},4000);
What could be the reason for this? What am I missing?
kill() sends a Unix signal. These are represented by numbers. You should pass the number of a signal to kill(), not the PID.
Try
import signal
print(signal.SIGTERM)
That probably prints 15 which is the number of the signal TERM (which normally terminates the process it is sent to).
In your program you could call
ls.kill(signal.SIGTERM)
In fact, unlike the Linux kill() command, which takes the process pid to kill and a signal as parameters, Nodejs ChildProcess subprocess.kill() expects only the signal argument (as string according to the documentation).
subprocess.kill([signal])
That makes sense because the subprocess already knows its pid (the one you get when using subprocess.pid) so you don't need to provide it again.
To kill your process, you can pass a valid signal to the .kill() method:
ls.kill('SIGTERM');
Or, you could also simply call the .kill() method of your subprocess without any arguments, which is equivalent to call it with the 'SIGTERM' signal.
ls.kill()
How can I start and stop a python script from a NodeJS server? I have seen the module "python-shell", but it doesn't provide a way to kill the script after running it.
Use child_process.
Example from the doc:
const { spawn } = require('child_process');
const child = spawn('python3', ['script.py']);
child.on('close', (code, signal) => {
console.log(
`child process terminated due to receipt of signal ${signal}`);
});
// Send SIGTERM to process
child.kill('SIGTERM');