从 nodejs 中的 child_process.spawn's stderr 读取所有内容
Read everything from child_process.spawn's stderr in nodejs
尝试通过 child_process.spawn()
从 nodejs 运行 fping
是并通过 cp.stderr.on('data')
捕获输出有时会导致缓冲区中的数据不完整。这是我的示例片段:
const ChildProcess = require('child_process');
const args = [
'-A','-c10','-b1472','-B1',
'-r0','-O0','-q', '-p100',
'google.com', 'slack.com', 'github.com'
];
function runChildProcess() {
const child = ChildProcess.spawn('fping', args);
child.on('exit', (code) =>
console.log('Process exited with code', code)
);
child.stdout.on('data', (data) => {
console.log('stdout:', data.toString().length, 'chars');
});
child.stderr.on('data', (data) => {
console.log('stderr:', data.toString().length, 'chars');
});
}
setInterval(runChildProcess, 1500);
这会产生如下输出:
stderr: 219 chars
Process exited with code 0
stderr: 208 chars
stderr: 11 chars
Process exited with code 0
stderr: 218 chars
stderr: 1 chars
Process exited with code 0
stderr: 219 chars
Process exited with code 0
stderr: 219 chars
Process exited with code 0
stderr: 219 chars
Process exited with code 0
stderr: 218 chars
stderr: 1 chars
Process exited with code 0
如您所见,有时它会调用回调两次,有时会调用一次,我有几次它被调用了 3 或 4 次,读取量很小。有没有办法确保读取所有可用数据,而不仅仅是其中的一部分?
您应该监听 end
事件。
data
事件可能会被多次调用 - 它会为每个接收到的块调用。所有块都应该收集在一起,例如在一个数组中。 end
事件表示该可读流 (child.stderr
) 中没有更多数据可使用。
请参阅下面使用 end
事件对代码稍作更改的版本(改为使用 setTimeout 和 ping):
const ChildProcess = require('child_process');
const args = [
'google.com'
];
function runChildProcess() {
var stdoutChunks = [], stderrChunks = [];
const child = ChildProcess.spawn('ping', args);
child.on('exit', (code) =>
console.log('Process exited with code', code)
);
child.stdout.on('data', (data) => {
stdoutChunks = stdoutChunks.concat(data);
});
child.stdout.on('end', () => {
var stdoutContent = Buffer.concat(stdoutChunks).toString();
console.log('stdout chars:', stdoutContent.length);
console.log(stdoutContent);
});
child.stderr.on('data', (data) => {
stderrChunks = stderrChunks.concat(data);
});
child.stderr.on('end', () => {
var stderrContent = Buffer.concat(stderrChunks).toString();
console.log('stderr chars:', stderrContent.length);
console.log(stderrContent);
});
}
setTimeout(runChildProcess, 0);
尝试通过 child_process.spawn()
从 nodejs 运行 fping
是并通过 cp.stderr.on('data')
捕获输出有时会导致缓冲区中的数据不完整。这是我的示例片段:
const ChildProcess = require('child_process');
const args = [
'-A','-c10','-b1472','-B1',
'-r0','-O0','-q', '-p100',
'google.com', 'slack.com', 'github.com'
];
function runChildProcess() {
const child = ChildProcess.spawn('fping', args);
child.on('exit', (code) =>
console.log('Process exited with code', code)
);
child.stdout.on('data', (data) => {
console.log('stdout:', data.toString().length, 'chars');
});
child.stderr.on('data', (data) => {
console.log('stderr:', data.toString().length, 'chars');
});
}
setInterval(runChildProcess, 1500);
这会产生如下输出:
stderr: 219 chars
Process exited with code 0
stderr: 208 chars
stderr: 11 chars
Process exited with code 0
stderr: 218 chars
stderr: 1 chars
Process exited with code 0
stderr: 219 chars
Process exited with code 0
stderr: 219 chars
Process exited with code 0
stderr: 219 chars
Process exited with code 0
stderr: 218 chars
stderr: 1 chars
Process exited with code 0
如您所见,有时它会调用回调两次,有时会调用一次,我有几次它被调用了 3 或 4 次,读取量很小。有没有办法确保读取所有可用数据,而不仅仅是其中的一部分?
您应该监听 end
事件。
data
事件可能会被多次调用 - 它会为每个接收到的块调用。所有块都应该收集在一起,例如在一个数组中。 end
事件表示该可读流 (child.stderr
) 中没有更多数据可使用。
请参阅下面使用 end
事件对代码稍作更改的版本(改为使用 setTimeout 和 ping):
const ChildProcess = require('child_process');
const args = [
'google.com'
];
function runChildProcess() {
var stdoutChunks = [], stderrChunks = [];
const child = ChildProcess.spawn('ping', args);
child.on('exit', (code) =>
console.log('Process exited with code', code)
);
child.stdout.on('data', (data) => {
stdoutChunks = stdoutChunks.concat(data);
});
child.stdout.on('end', () => {
var stdoutContent = Buffer.concat(stdoutChunks).toString();
console.log('stdout chars:', stdoutContent.length);
console.log(stdoutContent);
});
child.stderr.on('data', (data) => {
stderrChunks = stderrChunks.concat(data);
});
child.stderr.on('end', () => {
var stderrContent = Buffer.concat(stderrChunks).toString();
console.log('stderr chars:', stderrContent.length);
console.log(stderrContent);
});
}
setTimeout(runChildProcess, 0);