NodeJS exec / spawn stdout отключает поток на 8192 символах

Я использую MacOS, Node v12 и использую дочерний процесс (exec / spawn / execSync / spawnSync) для выполнения команды оболочки, которая может возвращать более 8192 символов. Однако в моем методе nodeJS, который вызывает дочерний процесс, я получаю только до 8192 символов и не более того. (8192 является размером пула по умолчанию для буфера).

Я попытался увеличить размер maxBuffer в разделе Параметры до значения больше 8192, но это ни на что не повлияло.

Я также пробовал выполнить ту же команду с exec, spawn, execSync и spawnSync, и все они ведут себя одинаково. Тот же результат.

Когда я бегу:

 exec(shellCommand, { encoding: "buffer", maxBuffer: 16384 }, (error, stdout, stderr) => {
     console.log('stdout--> length: ', stdout.length, '<--->', stdout)
 });

Я получил:

stdout--> length: 8192 <---> <Buffer 7b 22 72 65 73 75 6c 74 22 3a 5b 7b 22 70 72 6f 6a 65 63 74 4e 61 6d 65 22 3a 22 73 65 65 64 73 22 2c 22 74 65 6d 70 6c 61 74 65 4e 61 6d 65 22 3a 22 ... 8142 more bytes>

Я знаю, что возвращаемые данные больше 8192, потому что, когда я запускаю команду оболочки в оболочке и проверяю длину, она превышает 8192.

Кроме того, и это вызывает недоумение, когда я устанавливаю для дочернего процесса 'stdio параметр ' наследовать ', например:

execSync(shellCommand, { encoding: "buffer", stdio:"inherit" });

(который говорит об использовании родительского стандартного вывода, в моем случае это консоль NodeJS )

Я вижу полный ответ в консоли, на которой работает NodeJS.

Я также читал аналогичную проблему на github, но это не помогло.

Как мне выполнить команду оболочки в NodeJS и получить полный ответ?


person Nik    schedule 05.12.2019    source источник


Ответы (3)


попробуй это :

const { spawn } = require('child_process');
const cmd = spawn('command', ['arg1', 'arg2']);
let bufferArray= []
/*cmd.stdout.setEncoding('utf8'); sets encdoing
 defualt encoding is buffer
*/
cmd.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
  bufferArray.push(data)
});

cmd.stderr.on('data', (data) => {
  console.error(`stderr: ${data}`);
});

cmd.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
  let dataBuffer =  Buffer.concate(bufferArray];
  console.log(dataBuffer.toString())
});

это может быть полезно: порожденный потомок Node.js обработать и получить вывод терминала в реальном времени

person Sandeep Patel    schedule 05.12.2019

Оказывается, у команды оболочки был оператор process.exit(), который вызывается до того, как буфер stdout будет полностью очищен.

Таким образом, stdout отправит 8192 символа, и, поскольку он асинхронный, процесс перейдет к следующему оператору, одним из которых является process.exit (), и он убьет процесс, прежде чем очистить остальную часть буфера stdout.

TL; DR - exec / spawn работает правильно, команда оболочки завершается до того, как стандартный вывод будет полностью сброшен

person Nik    schedule 13.12.2019

Размер буфера по умолчанию для child_process.exec составляет 1 МБ, поэтому постарайтесь не передавать maxBuffer; однако было бы гораздо лучше использовать child_process.spawn, чтобы получить результат как транслировать.

person w00t    schedule 05.12.2019
comment
попробовал без maxBuffer и с spawn, но получил тот же результат - person Nik; 05.12.2019