Node.js 为什么我通过spawn()创建的节点子进程挂起?
我正在使用spawn()进行git调用。有时它工作得很好,但另一些时候它似乎是挂着的。我没有看到任何事件触发(错误、退出、关闭),但我看到了该过程确实成功完成的证据Node.js 为什么我通过spawn()创建的节点子进程挂起?,node.js,spawn,Node.js,Spawn,我正在使用spawn()进行git调用。有时它工作得很好,但另一些时候它似乎是挂着的。我没有看到任何事件触发(错误、退出、关闭),但我看到了该过程确实成功完成的证据 var spawn = require('child_process').spawn; spawn('git', ['push', 'origin', 'master']) .on('error', function(error) { console.log("ERROR: DETAILS: " + error);
var spawn = require('child_process').spawn;
spawn('git', ['push', 'origin', 'master'])
.on('error', function(error) {
console.log("ERROR: DETAILS: " + error);
})
.on('close', function(code) {
console.log("SUCCESS: CODE: " + code);
})
.on('exit', function(code) {
console.log("EXIT: CODE: " + code);
})
事实证明,一旦stderr缓冲区超过24kb,就必须从中读取,否则就看不到任何要完成的事件。可能的解决办法:
spawn('git', ['push', 'origin', 'master'], {stdio: 'ignore'});
请参阅Node ChildProcess doc以了解所有可能性-有很多var git = spawn('git', ['push', 'origin', 'master']);
...
git.stderr.pipe(process.stderr);
git.stdout.pipe(process.stdout);
一个可复制的案例已包含在本文件中。我相信退出不触发是一个错误,因为不同的行为取决于缓冲区的大小。事实证明,这正是处理子进程时的方式。您必须对stdio管道执行某些操作,否则子进程将面临挂起的风险,因为它的管道已满。另请参见。在这种情况下,孩子没有被吊死,而是已经离开了。但是,节点代码不接收任何事件。在子进程消失的地方,我也看到了同样的情况,但节点从未触发退出或关闭事件,并且我的节点代码处于死锁状态,等待不发生的事情发生。对我来说,误差是间歇性的,不能100%可靠地再现。
var git = spawn('git', ['push', 'origin', 'master']);
...
git.stderr.pipe(process.stderr);
git.stdout.pipe(process.stdout);