NodeJS 在 readline 中获取颜色

Web*_*kie 5 console readline node.js

我有一个 NodeJS 应用程序需要使用 执行一些命令spawn,我​​正在读取输出以供以后处理,使用readline它可以完美地工作。

但我还需要获取文本的颜色,例如:在执行另一个Node.js使用chalkmodule.txt 的脚本时。

如何才能做到这一点?

到目前为止,这是我的代码:

const spawn = require('child_process').spawn;
const readline = require('readline');

let myCommand = spawn(<command>, [<args...>], { cwd: dirPath });

readline.createInterface({
  input    : myCommand.stdout,
  terminal : true
}).on('line', (line) => handleOutput(myCommand.pid, line));

readline.createInterface({
  input    : myCommand.stderr,
  terminal : true
}).on('line', (line) => handleErrorOutput(myCommand.pid, line));

myCommand.on('exit', (code) => {
  // Do more stuff ..
});
Run Code Online (Sandbox Code Playgroud)

更新

Amr K. Aly 的答案确实有效,但在执行外部NodeJS脚本时它返回空颜色。

我的代码(index.js)

const spawn = require('child_process').spawn;
const readline = require('readline');

let myCommand = spawn('node', ['cmd.js']);

readline.createInterface({
  input: myCommand.stdout,
  terminal: true
}).on('line', (line) => handleOutput(myCommand.pid, line));

readline.createInterface({
  input: myCommand.stderr,
  terminal: true
}).on('line', (line) => handleErrorOutput(myCommand.pid, line));

myCommand.on('exit', (code) => {
  // Do more stuff ..
});

function handleErrorOutput(obj, obj2) {}

function handleOutput(obj, line, a, b, c) {
  //PRINT TEXT WITH ANSI FORMATING
  console.log(line);

  //REGEX PATTERN TO EXTRACT COLOR
  var options = Object.assign({
    onlyFirst: false
  });

  const pattern = [
    '[\\u001B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
    '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'
  ].join('|');

  var regex = new RegExp(pattern, options.onlyFirst ? undefined : 'g');
  var ansiColor = (line.match(regex));

  //PRINT EXTRACTED ANSI
  console.log("ANSI COLOR CODE :");
  console.log(ansiColor);
}
Run Code Online (Sandbox Code Playgroud)

cmd.js

const chalk = require('chalk');

console.log(chalk.blue('Blue Hello world!'));
console.log(chalk.green('green Hello world!'));
console.log(chalk.red('red Hello world!'));
Run Code Online (Sandbox Code Playgroud)

我的结果

Index.js 结果

A.A*_*.A. 5

问题:

打印回您读取的文本流时,您看不到颜色,因为您已将terminalcreateInterface 中的选项设置为true。这会导致 createInterface() 不返回 ANSI/VT100 编码。

解决方案:

terminal需要设置该选项false,以便使用 ANSI/VT100 对文本进行编码来自 Nodejs 文档: terminal <boolean> true if the input and output streams should be treated like a TTY, and have ANSI/VT100 escape codes written to it. Default: checking isTTY on the output stream upon instantiation.请参阅readline.createInterface(options) 文档

readline.createInterface({
input: myCommand.stdout,
terminal: true//<== NEEDS TO BE SET TO FALSE 
}).on('line', (line) => handleOutput(myCommand.pid, line));
Run Code Online (Sandbox Code Playgroud)

设置为 后terminalfalse返回的文本将采用 ANSI/VT100 编码。然后,您需要提取与颜色相关的 ANSI/VT100 编码,并将其更改为您需要的任何颜色格式。

请参阅下面的修改后的代码和输出,其中添加了正则表达式来提取 ANSI 颜色代码。您需要添加自己的逻辑来处理 ANSI 转义颜色。

const spawn = require('child_process').spawn;
const readline = require('readline');
const chalk = require('chalk');

 //Testing on windows 10
let myCommand = spawn(process.env.comspec, ['/c', 'echo ' + chalk.red('Hello world!'), ], {
    // cwd: dirPath
});

readline.createInterface({
    input: myCommand.stdout,
    terminal: false
}).on('line', (line) => handleOutput(myCommand.pid, line));

readline.createInterface({
    input: myCommand.stderr,
    terminal: false
}).on('line', (line) => handleErrorOutput(myCommand.pid, line));

myCommand.on('exit', (code) => {
    // Do more stuff ..
});

function handleErrorOutput(obj, obj2) {}

function handleOutput(obj, line) {

    //PRINT TEXT WITH ANSI FORMATING
    console.log(line);

    //REGEX PATTERN TO EXTRACT COLOR
    var options = Object.assign({
        onlyFirst: false
    });

    const pattern = [
        '[\\u001B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
        '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'
    ].join('|');

    var regex = new RegExp(pattern, options.onlyFirst ? undefined : 'g');
    var ansiColor = (line.match(regex));

    //PRINT EXTRACTED ANSI
    console.log("ANSI COLOR CODE :");
    console.log(ansiColor);
}
Run Code Online (Sandbox Code Playgroud)

上面代码的输出:

上面代码的输出:

编辑:

Chalk 会自动检测您是否正在向 TTY 写入或终端不支持颜色并禁用着色。您可以通过设置环境变量FORCE_COLOR=1或传递 a--color作为参数来强制执行它。

如果将代码更改为下面代码片段中的行,Chalk 应该正确添加样式。

let myCommand = spawn('node', ['test.js', '--color', ], {


}); 
Run Code Online (Sandbox Code Playgroud)

输出:

代码输出