【问题标题】:Retaining output colors when shelling out to node脱壳到节点时保留输出颜色
【发布时间】:2013-09-20 10:53:42
【问题描述】:

我有一个小 Grunt 任务,它通过节点运行并运行“composer install”。

var done = this.async();

var exec = require('child_process').exec;
var composer = exec(
    'php bin/composer.phar install',
    function(error, stdout, stderr) {
        done(error===null);
    }
);

composer.stdout.on(
    'data',
    grunt.log.write
);

如您所见,我将这个子进程的标准输出输出到 grunt.log。除了输出全部采用我的默认控制台颜色外,所有输出都显示得很好并且符合预期。如果我直接运行“composer install”,我会得到高亮显示,从而提高可读性。

由于我是 node、Grunt 和一般情况下的新手,我不确定着色在系统的哪个部分丢失,甚至不确定如何有效地调试。

【问题讨论】:

    标签: javascript node.js stdout gruntjs child-process


    【解决方案1】:

    在某些情况下,命令行程序在不通过终端运行时会阻止彩色输出,因此您需要指示程序输出 ANSI 转义序列。

    在这种情况下,就像添加一个'--ansi'标志一样简单,例如:

    var done = this.async();
    
    var exec = require('child_process').exec;
    var composer = exec(
        'php bin/composer.phar install --ansi',
        function(error, stdout, stderr) {
            done(error===null);
        }
    );
    
    composer.stdout.on(
        'data',
        grunt.log.write
    );
    

    【讨论】:

    • 很高兴知道它是否有效(现在无法测试)!
    • 在这种情况下--ansi 是否仅适用于php CLI 命令?或者是一些适用于任何命令的通用参数?
    • @bigp 这仅适用于 php 命令(实际上它是 composer 参数,而不是 php 参数)
    【解决方案2】:

    使用 spawn 和选项 stdio='inherit' 可以包含输出颜色。

    来自文档:

    选项(对象)

    • cwd String 子进程当前工作目录
    • stdio (Array|String) 子级的 stdio 配置。 (见下文)

    ...

    作为简写,stdio 参数也可以是以下之一 字符串,而不是数组:

    • 忽略 - ['忽略', '忽略', '忽略']
    • 管道 - ['管道', '管道', '管道']
    • 继承 - [process.stdin, process.stdout, process.stderr] 或 [0,1,2]

    这是一个工作代码的例子:

    require('child_process')
      .spawn('npm', ['install'], {stdio:'inherit'})
      .on('exit', function (error) {
    
        if(!error){
          console.log('Success!');
        }
    
        }
      });
    

    我想让exec 工作,但我没有找到访问相同选项的方法。

    【讨论】:

    • 这是正确的。但不幸的是,这也意味着您无法捕获输出。 inherit 只是打印出来而已。
    • @Marc 如果您仍想捕获输出,则使用{stdio:'pipe'} 作为 spawn() 的第三个参数。要显示颜色,请执行以下操作:var colors = require('colors'); colors.enabled = true;.
    【解决方案3】:

    如果像我一样,您正在生成子进程 node 而不是非节点脚本,您可能会发现 --ansi--color 选项在保留子进程的彩色输出方面收效甚微node 进程。

    相反,您应该inherit 当前进程的stdio 的实例。

    我的特定用例涉及将节点服务器分叉为后台任务,以便针对活动的 HTTP 接口执行端到端测试套件。这是我的最终解决方案:

    var child = spawn('node', ['webserver/server.js'], {
      args: ['--debug'],
      env: _.extend(process.env, {
        MOCK_API: mockApi
      }),
    
      // use process.stdout to retain ansi color codes
      stdio: [process.stdin, process.stdout, 'pipe']
    });
    
    // use custom error buffer in order to throw using grunt.fail()
    var errorBuffer = '';
    child.stderr.on('data', function(data) {
      errorBuffer += data;
    });
    
    child.on('close', function(code) {
      if (code) {
        grunt.fail.fatal(errorBuffer, code);
      } else {
        done();
      }
    });
    

    【讨论】:

    • OP 没有执行node 命令(它们正在生成php 进程)。所以这不是一个解决方案。此外,--colors 不再是 node 的选项。
    【解决方案4】:

    --colors 标志对我有用。节点版本 6.8.0...

    --colors, -c 强制启用颜色 [boolean]

    如果返回任何颜色,以下通用示例将打印颜色...

    var exec = require('child_process').exec;
    
    exec('node someCommand --colors', function (error, stdout, stderr) {
    
      console.log(stdout || stderr); // yay colors!
    });
    

    【讨论】:

    • 简单而现代 - 伙计们,你需要使用这个解决方案!
    • OP 没有执行node 命令(他们正在生成php 进程)。所以这不是一个解决方案。此外,--colors 不再是 node 的选项。
    【解决方案5】:

    我也在场。如果你:

    • 不想继承子标准输出
    • 不知道将要执行哪个命令(然后您不知道 --ansi 或 --colors 中的哪一个可以工作)

    然后你应该从节点生成一个 PTY。正是出于这个原因,我创建了this node package

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-31
      • 1970-01-01
      • 2017-01-07
      • 1970-01-01
      • 2013-06-09
      • 2013-07-03
      • 2015-11-05
      • 1970-01-01
      相关资源
      最近更新 更多