Nodejs 使用 spawn 如何保持原来命令行的输出样式?
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}`)
}
})
遇到两个问题:
- 如何打印 codePushProcess 本身的命令? 在 ChildProcess 里找不到有这个属性.
- code-push 这个命令会向 stdout 输出一个动态的上传进度条, 但是使用 console.log 输出会全部变成 string 形式, 在 bash 下都是单色, 并且动态的进度条也没有, 如何解决?
解决了:
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环境中输出颜色。
这种方法适用于大多数需要保持输出样式的场景,但具体实现可能需要根据命令和上下文进行调整。