Masalah buffer stdout menggunakan node child_process

92

Saya mencoba mengeksekusi curl menggunakan node child_process untuk mendapatkan file JSON (sekitar 220Ko) dari folder bersama di jaringan lokal. Tapi sebenarnya mengembalikan masalah buffer yang tidak bisa saya pikirkan. Ini kode saya:

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

Dan inilah kesalahan yang saya dapatkan:

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)
Yonnaled
sumber

Jawaban:

161

Anda perlu menggunakan dan mengatur maxBufferopsi saat menggunakan child_process.exec. Dari dokumentasi :

maxBuffer menentukan jumlah data terbesar yang diizinkan di stdout atau stderr - jika nilai ini terlampaui maka proses turunan akan dihentikan.

Dokumentasi juga menyatakan bahwa nilai default maxBufferadalah 200KB.

Sebagai contoh, ukuran buffer maksimum ditingkatkan menjadi 500KB dalam kode berikut:

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

Selain itu, Anda mungkin ingin membaca tentang http.getuntuk melihat apakah itu mampu mencapai apa yang Anda coba lakukan.

Tim Cooper
sumber
Ini menyelesaikan masalah saya, terima kasih! Folder bersama sebenarnya di bawah protokol webdav yang memerlukan otentikasi intisari, itulah mengapa saya menggunakan curl yang menanganinya dengan sangat mudahcurl --digest http://login:password@" + ip + "/webdav/file.json
Yonnaled
Default ini sangat kecil. Ini adalah kedua kalinya saya digigit oleh ini dengan cara yang sulit ditemukan.
jlh
3
Standarnya sekarang 1MB @jlh, nodejs.org/api/…
Carlos
57

Saya memiliki masalah serupa dan saya memperbaikinya berpindah dari exec ke 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);
});
lsampaio
sumber
10
Ini tampaknya menjadi solusi yang paling tepat dari keduanya
Hashbrown
1
Jawaban ini belum tentu yang paling tepat. Menurut saya, keluaran konsol yang dimaksud bisa jadi hanya sebuah contoh. Hampir tidak ada orang yang akan mengambil file 200KB untuk dibuang ke konsol. Namun, jika process.execdigunakan dalam hal-hal seperti alat CLI, maka ya, beralih ke spawnharus menjadi cara yang tepat.
Pavel Gatilov
1
wow ... bibit itu keren. Ini bahkan tidak menggunakan panggilan balik atau janji ... hanya acara. Itu bisa sangat berguna untuk streaming stdout ke konsol. @Pavel Gatilov, itulah yang kami lakukan. FFMpeg suka menunjukkan kemajuan setiap detik ... yang berdampak pada buffer
Ray Foss