Nodejs 使用 spawn 如何保持原来命令行的输出样式?

发布于 1周前 作者 bupafengyu 来自 nodejs/Nestjs

Nodejs 使用 spawn 如何保持原来命令行的输出样式?

我在使用 Node.js 里 spawn 来执行一段命令:

const codePushProcess = spawn('code-push', [
  'release-react',
  `rrs-${platform}`,
  platform,
  `--deploymentName=${deploymentName}`,
  `--description=${desc}`,
  `--targetBinaryVersion=${version}`,
  '-m'
])
codePushProcess.stdout.on('data', chunk => {
  console.log(chunk.toString('utf8'))
})

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

codePushProcess.on('close', code => {
  if (code === 0) {
    console.log('CodePush Success!')
  } else {
    console.log(`CodePush process exited with code ${code}`)
  }
})

遇到两个问题:

  1. 如何打印 codePushProcess 本身的命令? 在 ChildProcess 里找不到有这个属性.
  2. code-push 这个命令会向 stdout 输出一个动态的上传进度条, 但是使用 console.log 输出会全部变成 string 形式, 在 bash 下都是单色, 并且动态的进度条也没有, 如何解决?

3 回复

贴个对比图:


解决了:

spawn(‘code-push’, args, { stdio: ‘inherit’ })


这个属性会将 stdio 传递给 parent process.

https://nodejs.org/api/child_process.html#child_process_options_stdio

’inherit’: Pass through the corresponding stdio stream to/from the parent process. In the first three positions, this is equivalent to process.stdin, process.stdout, and process.stderr, respectively. In any other position, equivalent to ‘ignore’.

在 Node.js 中使用 child_process.spawn 方法执行外部命令时,默认情况下,输出流(stdout 和 stderr)是缓冲的,这意味着它们会以纯文本形式返回,而不包含原命令行中的颜色、格式等样式信息。为了保持这些样式信息,你需要将这些流作为数据流来处理,而不是将它们缓冲为字符串。

以下是一个示例代码,展示了如何使用 spawn 并保持命令行的输出样式:

const { spawn } = require('child_process');
const readline = require('readline');

const ls = spawn('ls', ['-l', '--color=always'], {
  stdio: ['ignore', 'pipe', 'pipe']
});

const rl = readline.createInterface({
  input: ls.stdout,
  output: process.stdout,
  terminal: true
});

ls.stdout.on('data', (data) => {
  process.stdout.write(data);
});

ls.stderr.on('data', (data) => {
  process.stderr.write(data);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
  rl.close();
});

在这个例子中,我们使用了 readline 模块来逐行读取 ls 命令的输出,并立即将其写入到 process.stdout,这样保持了颜色和其他样式信息。注意,我们使用了 --color=always 选项来确保 ls 命令总是输出颜色信息,即使它通常不会在非TTY环境中输出颜色。

这种方法适用于大多数需要保持输出样式的场景,但具体实现可能需要根据命令和上下文进行调整。

回到顶部