簡體   English   中英

NodeJS 在 readline 中獲取顏色

[英]NodeJS get color in readline

我有一個 NodeJS 應用程序需要使用spawn執行一些命令,我​​正在使用readline讀取輸出以供以后處理,它可以完美地工作。

但我還需要獲取文本的顏色,例如:執行另一個使用chalk模塊的Node.js腳本時。

如何做到這一點?

到目前為止,這是我的代碼:

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 ..
});

更新

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);
}

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!'));

我的結果

Index.js 結果

問題:

打印回您閱讀的文本流時您看不到顏色,因為您已將 createInterface 中的terminal選項設置為true 這會導致 createInterface() 不返回 ANSI/VT100 編碼。

解決方案:

terminal選項需要設置為false以便文本將使用 ANSI/VT100 編碼來自 Nodejs Docs: 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. 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));

terminal設置為false ,返回的文本將采用 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);
}

上面代碼的輸出:

上面代碼的輸出:

編輯:

Chalk 會自動檢測您是否正在寫入 TTY 或終端不支持顏色並禁用着色。 您可以通過設置環境變量FORCE_COLOR=1或通過傳遞--color作為參數來強制它。

如果您將代碼更改為以下代碼段中的行,Chalk 應該正確添加樣式。

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


}); 

輸出:

代碼輸出

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM