Stdout-Pufferproblem mit dem Knoten child_process

91

Ich versuche, curl mit dem Knoten child_process auszuführen, um eine JSON-Datei (ca. 220Ko) aus einem freigegebenen Ordner in einem lokalen Netzwerk abzurufen. Aber es gibt tatsächlich ein Pufferproblem zurück, das ich nicht durchstehen kann. Hier ist mein Code:

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

Und hier ist der Fehler, den ich bekomme:

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
quelle

Antworten:

161

Sie müssen die maxBufferOption verwenden und festlegen, wenn Sie verwenden child_process.exec. Aus der Dokumentation :

maxBuffer Gibt die größte Datenmenge an, die für stdout oder stderr zulässig ist. Wenn dieser Wert überschritten wird, wird der untergeordnete Prozess beendet.

In der Dokumentation wird außerdem angegeben, dass der Standardwert von maxBuffer200 KB ist.

Beispielsweise wird die maximale Puffergröße im folgenden Code auf 500 KB erhöht:

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

Darüber hinaus möchten Sie möglicherweise lesen http.get, ob es in der Lage ist, das zu erreichen, was Sie versuchen.

Tim Cooper
quelle
Dies hat mein Problem gelöst, danke! Der freigegebene Ordner befindet sich tatsächlich unter dem Webdav-Protokoll, das eine Digest-Authentifizierung erfordert. Deshalb verwende ich Curl, mit dem es sehr einfach zu curl --digest http://login:password@" + ip + "/webdav/file.json
handhaben ist
Diese Standardeinstellung ist lächerlich klein. Dies ist das zweite Mal, dass ich auf eine schwer zu findende Weise davon gebissen wurde.
jlh
3
Der Standardwert ist jetzt 1 MB
Carlos
57

Ich hatte ein ähnliches Problem und habe es behoben, indem ich von exec zu spawn gewechselt bin:

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
quelle
10
Dies scheint die am besten geeignete Lösung der beiden zu sein
Hashbrown
1
Diese Antwort ist nicht unbedingt die am besten geeignete. Ich denke, die Konsolenausgabe in der Frage könnte nur ein Beispiel sein. Kaum jemand würde eine 200-KB-Datei abrufen, um sie auf die Konsole zu werfen. Wenn process.execes jedoch in Dingen wie CLI-Tools verwendet wird, spawnsollte der Wechsel zu der richtige Weg sein.
Pavel Gatilov
1
wow ... laich ist cool. Es werden nicht einmal Rückrufe oder Versprechen verwendet ... nur Ereignisse. Das könnte sehr nützlich sein, um stdout auf die Konsole zu streamen. @ Pavel Gatilov, genau das machen wir. FFMpeg zeigt gerne jede Sekunde Fortschritte ... was den Puffer stark belastet
Ray Foss