Sự cố bộ đệm Stdout khi sử dụng node child_process


91

Tôi đang cố gắng thực thi curl bằng cách sử dụng node child_process để lấy tệp JSON (khoảng 220Ko) từ một thư mục được chia sẻ trong mạng cục bộ. Nhưng nó thực sự trả về một vấn đề bộ đệm mà tôi không thể giải quyết. Đây là mã của tôi:

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);
})

Và đây là lỗi tôi nhận được:

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)

Câu trả lời:


161

Bạn cần sử dụng và thiết lập maxBuffertùy chọn khi sử dụng child_process.exec. Từ tài liệu :

maxBuffer chỉ định lượng dữ liệu lớn nhất được phép trên stdout hoặc stderr - nếu giá trị này bị vượt quá thì tiến trình con sẽ bị hủy.

Tài liệu cũng nói rằng giá trị mặc định của maxBufferlà 200KB.

Ví dụ: kích thước bộ đệm tối đa được tăng lên 500KB trong đoạn mã sau:

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

Ngoài ra, bạn có thể muốn đọc về http.getđể xem liệu nó có khả năng đạt được những gì bạn đang cố gắng làm hay không.


Điều này đã giải quyết vấn đề của tôi, cảm ơn! Các thư mục chia sẻ thực sự là dưới giao thức WebDAV mà đòi hỏi một tiêu hóa xác thực, đó là lý do tại sao tôi đang sử dụng curl mà xử lý nó rất dễ dàng vớicurl --digest http://login:password@" + ip + "/webdav/file.json
Yonnaled

Mặc định này là nhỏ một cách kỳ cục. Đây là lần thứ hai tôi bị nó cắn một cách khó tìm.
jlh

3
Giá trị mặc định bây giờ là 1MB @jlh, nodejs.org/api/…
Carlos

57

Tôi gặp sự cố tương tự và tôi đã khắc phục sự cố khi chuyển từ hành động sang sinh sản:

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
Đây có vẻ là thích hợp nhất giải pháp của hai
Hashbrown

1
Câu trả lời này không nhất thiết là câu trả lời thích hợp nhất. Tôi nghĩ đầu ra bảng điều khiển trong câu hỏi có thể chỉ là một ví dụ. Hầu như ai đó sẽ tìm nạp một tệp 200KB để ném nó vào bảng điều khiển. Tuy nhiên, nếu process.execđược sử dụng trong những thứ như công cụ CLI, thì có, chuyển sang spawnnên là cách tốt nhất.
Pavel Gatilov

1
wow ... đẻ trứng thật tuyệt. Nó thậm chí không sử dụng cuộc gọi lại hoặc lời hứa ... chỉ là sự kiện. Điều đó có thể thực sự hữu ích cho việc phát trực tuyến stdout tới bảng điều khiển. @Pavel Gatilov, đó chính xác là những gì chúng tôi đang làm. FFMpeg thích hiển thị sự tiến bộ mỗi giây ... điều này có ảnh hưởng đến bộ đệm
Ray Foss
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.