ปัญหาบัฟเฟอร์ Stdout โดยใช้โหนด child_process


92

ฉันกำลังพยายามดำเนินการ curl โดยใช้โหนด child_process เพื่อรับไฟล์ 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)

คำตอบ:


161

คุณจำเป็นต้องใช้และการตั้งค่าตัวเลือกเมื่อใช้maxBuffer child_process.execจากเอกสารประกอบ :

maxBuffer ระบุจำนวนข้อมูลสูงสุดที่อนุญาตบน stdout หรือ stderr - หากเกินค่านี้กระบวนการย่อยจะถูกฆ่า

เอกสารยังระบุด้วยว่าค่าเริ่มต้นmaxBufferคือ 200KB

ตัวอย่างเช่นขนาดบัฟเฟอร์สูงสุดจะเพิ่มขึ้นเป็น 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

ค่าเริ่มต้นนี้มีขนาดเล็กมาก นี่เป็นครั้งที่สองที่ฉันถูกกัดด้วยวิธีที่หายาก
jlh

3
ค่าเริ่มต้นตอนนี้คือ 1MB @jlh, nodejs.org/api/…
Carlos

57

ฉันมีปัญหาที่คล้ายกันและฉันได้แก้ไขแล้วโดยเปลี่ยนจากผู้บริหารไปสู่การวางไข่:

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
ว้าว ... วางไข่ได้เจ๋ง มันไม่ได้ใช้การโทรกลับหรือสัญญา ... เพียงแค่เหตุการณ์ นั่นอาจเป็นประโยชน์อย่างมากสำหรับการสตรีม stdout ไปยังคอนโซล @Pavel Gatilov นั่นคือสิ่งที่เรากำลังทำอยู่ FFMpeg ชอบแสดงความคืบหน้าทุกวินาที ... ซึ่งต้องเสียค่าผ่านทางบัฟเฟอร์
Ray Foss
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.