在脱壳节点时保留输出颜色

我有一个小Grunt任务,通过节点popup,并运行“composer php安装”。

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

正如你所看到的,我将这个subprocess的stdout输出到grunt.log。 除了输出全部以我的默认控制台颜色显示之外,所有的输出都如预期般显示出色。 如果我直接运行“composer php安装”,我会突出显示,提高可读性。

由于我对节点,Grunt以及一般情况下的新手很陌生,因此我不确定系统的哪个部分颜色会丢失,甚至不知道如何高效地进行debugging。

在某些情况下,命令行程序在不通过terminal运行时会阻止彩色输出,因此您需要指示程序输出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 ); 

使用spawn与选项stdio ='inheritance'工作,包括输出颜色。

从文档:

选项(对象)

  • cwdstringsubprocess的当前工作目录
  • stdio(Array | String)子级的stdioconfiguration。 (见下文)

作为简写,stdio参数也可以是下列string之一,而不是数组:

  • 忽略 – ['忽略','忽略','忽略']
  • pipe道 – ['pipe道','pipe道','pipe道]]
  • inheritance – [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,但我没有find一种方法来访问相同的选项。

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

如果像我自己一样,生成一个子node进程而不是非节点的脚本,你可能会发现,– --ansi--color选项对于保留子node进程的彩色输出几乎没有成功。

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

我的特殊用例涉及到将一个节点服务器作为后台任务,以便对一个活动的HTTP接口执行一个端到端的testing套件。 这是我的最终解决scheme:

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