Problem z buforem standardowym używającym węzła child_process


92

Próbuję wykonać curl za pomocą węzła child_process, aby uzyskać plik JSON (około 220Ko) z folderu udostępnionego w sieci lokalnej. Ale w rzeczywistości zwraca problem z buforem, którego nie mogę rozwiązać. Oto mój kod:

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

A oto błąd, który otrzymuję:

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)

Odpowiedzi:


161

Musisz użyć i ustawić maxBufferopcję podczas używania child_process.exec. Z dokumentacji :

maxBuffer określa największą ilość danych dozwolonych na stdout lub stderr - jeśli ta wartość zostanie przekroczona, proces potomny jest zabijany.

Dokumentacja stwierdza również, że domyślna wartość maxBufferto 200 KB.

Na przykład maksymalny rozmiar bufora został zwiększony do 500 KB w następującym kodzie:

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

Dodatkowo możesz przeczytać o tym, http.getaby sprawdzić, czy jest w stanie osiągnąć to, co próbujesz zrobić.


To rozwiązało mój problem, dzięki! Folder współdzielony jest w rzeczywistości pod protokołem webdav, który wymaga uwierzytelnienia za pomocą skrótu, dlatego używam curl, który obsługuje go bardzo łatwocurl --digest http://login:password@" + ip + "/webdav/file.json
Yonnaled

To ustawienie domyślne jest śmiesznie małe. To już drugi raz, kiedy ugryzło mnie to w trudny do znalezienia sposób.
jlh

3
Wartość domyślna to teraz 1 MB @jlh, nodejs.org/api/ ...
Carlos

57

Miałem podobny problem i naprawiłem go przechodząc z exec na 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
Wydaje się, że jest to najbardziej odpowiednie rozwiązanie z dwóch
Hashbrown

1
Ta odpowiedź niekoniecznie jest najwłaściwsza. Myślę, że wyjście konsoli w pytaniu może być tylko przykładem. Mało kto pobrałby plik 200KB, żeby rzucić go na konsolę. Jeśli jednak process.execjest używany w takich narzędziach, jak narzędzia CLI, to tak, przejście na spawnpowinno być drogą do zrobienia.
Pavel Gatilov

1
wow ... spawn jest fajny. Nie używa nawet oddzwonień ani obietnic ... tylko wydarzenia. To może być naprawdę przydatne do przesyłania strumieniowego standardowego wyjścia do konsoli. @Pavel Gatilov, właśnie to robimy. FFMpeg lubi pokazywać postęp co sekundę ... co odbija się na buforze
Ray Foss
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.