NodeJS exec/spawn stdout 在 8192 个字符处截断流

NodeJS exec/spawn stdout cuts off the stream at 8192 characters

我在 MacOS、Node v12 上使用子进程 (exec/spawn/execSync/spawnSync) 执行 shell 命令,该命令可以 return 超过 8192 个字符。但是,回到我调用子进程的 nodeJS 方法中,我最多只能得到 8192 个字符,而且不会超过这个数。 (8192 seems to be the default pool size for a buffer)。

我尝试将 Options 中的 maxBuffer 大小增加到大于 8192 的任何值,但它不会影响任何内容。

我也尝试过 运行使用 exec、spawn、execSyncspawnSync 使用相同的命令,它们都是以同样的方式行事。同样的结果。

当我运行:

 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,因为当我在 shell 中 运行 命令 shell 并检查它的长度大于 8192.

此外,这是令人费解的一点,当我将子进程的 stdio 选项设置为 'inherit' 这样如:

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

(表示使用 parents stdout,在我的例子中是 NodeJS 的控制台)

我在控制台中看到了完整的响应,其中 NodeJS 是 运行ning。

我也在 github 上阅读了类似的问题,但它并没有真正帮助。

如何在 NodeJS 中执行 shell 命令并获得完整的响应?

child_process.exec 的默认缓冲区大小是 1MB, so try not passing a maxBuffer; however, it would be much better to use child_process.spawn,因此您可以将输出作为流。

试试这个:

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 spawn child process and get terminal output live

结果是 shell 命令有一个 process.exit() 语句在标准输出缓冲区完全刷新之前被调用。

因此 stdout 将发送 8192 个字符,并且由于它是异步的,因此进程将继续执行下一条语句,其中之一是 process.exit() 并且它将在清除其余的 stdout 之前终止进程缓冲区。

TL;DR - exec/spawn 正常工作,shell 命令在 stdout 完全刷新之前退出