节点 exec() 未触发所有数据事件

Ste*_*fan 3 javascript node.js

似乎足够大的标准输出输出节点不会触发data事件:

bash 脚本示例:

#!/usr/bin/env sh

for i in {1..100000}; do
    echo $i
done
Run Code Online (Sandbox Code Playgroud)

从 bash 运行上述脚本应该打印从 1 到 100k 的所有数字,每行一个数字

但是,当通过节点代理它时exec

#!/usr/bin/env node --harmony --harmony_destructuring --harmony_default_parameters

const {exec} = require('child_process');

let stdout = '';

const child = exec('./tmp.sh');

child.stdout.on('data', data => {
    stdout += data;
});

child.stdout.on('close', code => {
    if (code) process.exit(code);
    console.log(stdout.split('\n').slice(0, 3).join('\n'));
    console.log('...');
    console.log(stdout.split('\n').slice(-3).join('\n'));
});
Run Code Online (Sandbox Code Playgroud)

对于上面的脚本,我期望得到:

1
2
3
...
99998
99999
100000
Run Code Online (Sandbox Code Playgroud)

但是,当运行时它返回:

1
2
3
...
35984
35985
Run Code Online (Sandbox Code Playgroud)

大约三分之一的输出被截断。记录处理程序内部data显示仅使用 1 个块触发 1 个数据事件

我尝试监听该child.on('exit')事件,但得到了相同的结果(也stdout.on('exit')

exec替换为时效果相同spawn

node --version # v5.4.1
osx 10.10
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 5

child_process.exec()将标准输出缓冲到固定大小的缓冲区中。您可能会填充缓冲区,因此您不会获得其余的输出。

maxBuffer您可以传递一个选项.exec()来增大缓冲区,或者您可以使用.spawn()和接收无限的输出流。

有关相关信息,请参阅使用节点 child_process 的标准输出缓冲区问题

还值得一读:Difference Between spawn and exec of Node.js child_process and Stdout of Node.js child_process exec is cut short