使用节点child_process的标准输出缓冲区问题


91

我正在尝试使用节点child_process执行curl以从本地网络中的共享文件夹获取JSON文件(约220Ko)。但是它实际上返回了一个我无法解决的缓冲区问题。这是我的代码:

var exec = require('child_process').exec;

var execute = function(command, callback){
    exec(command, function(error, stdout, stderr){ callback(error, stdout); });
};

execute("curl http://" + ip + "/file.json", function(err, json, outerr) {
    if(err) throw err;
    console.log(json);
})

这是我得到的错误:

if(err) throw err;
          ^
Error: stdout maxBuffer exceeded.
    at Socket.<anonymous> (child_process.js:678:13)
    at Socket.EventEmitter.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:746:14)
    at Socket.EventEmitter.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:408:10)
    at emitReadable (_stream_readable.js:404:5)
    at readableAddChunk (_stream_readable.js:165:9)
    at Socket.Readable.push (_stream_readable.js:127:10)
    at Pipe.onread (net.js:526:21)

Answers:


161

使用时,您需要使用并设置maxBuffer选项child_process.exec。从文档中

maxBuffer 指定在stdout或stderr上允许的最大数据量-如果超出此值,则终止子进程。

该文档还指出默认值为maxBuffer200KB。

例如,以下代码将最大缓冲区大小增加到500KB:

var execute = function(command, callback){
    exec(command, {maxBuffer: 1024 * 500}, function(error, stdout, stderr){ callback(error, stdout); });
};

此外,您可能想阅读一下http.get,看看它是否能够实现您要尝试执行的操作。


这解决了我的问题,谢谢!共享文件夹实际上是在webdav协议下,需要摘要式身份验证,这就是为什么我使用curl可以轻松处理它的原因curl --digest http://login:password@" + ip + "/webdav/file.json
Yonnaled 2014年

这个默认值太小了。这是我第二次以一种难以捉摸的方式被这个问题所咬。
jlh

3
现在的默认值为1MB @ jlh,nodejs.org / api /…
卡洛斯

57

我遇到了类似的问题,并修复了从exec到spawn的问题:

var child = process.spawn('<process>', [<arg1>, <arg2>]);

child.stdout.on('data', function (data) {
  console.log('stdout: ' + data);
});

child.stderr.on('data', function (data) {
  console.log('stderr: ' + data);
});

child.on('close', function (code) {
    console.log('child process exited with code ' + code);
});


10
这似乎是两者中最合适的解决方案
Hashbrown

1
这个答案不一定是最合适的答案。我认为问题中的控制台输出可能只是一个例子。几乎没有人会获取200KB的文件以将其扔到控制台上。但是,如果process.exec用于CLI工具之类的东西,那么可以,切换到它spawn应该是方法。
Pavel Gatilov

1
哇...产卵很酷 它甚至都没有使用回叫或承诺……只是事件。这对于将标准输出流传输到控制台可能真的很有用。@Pavel Gatilov,这正是我们正在做的。FFMpeg喜欢每秒显示进度...这对缓冲区造成了损失
Ray Foss
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.