我有这样一个简单的脚本:

var exec = require('child_process').exec;

exec('coffee -cw my_file.coffee', function(error, stdout, stderr) {
    console.log(stdout);
});

我只是简单地执行一个命令来编译一个咖啡脚本文件。但是stdout永远不会显示在控制台中,因为命令永远不会结束(因为coffee的-w选项)。 如果我直接从控制台执行命令,我会得到这样的消息:

18:05:59 - compiled my_file.coffee

我的问题是:是否可以用node.js的exec来显示这些消息?如果是,怎么做?!

谢谢


当前回答

exec还将返回一个ChildProcess对象,它是一个EventEmitter对象。

var exec = require('child_process').exec;
var coffeeProcess = exec('coffee -cw my_file.coffee');

coffeeProcess.stdout.on('data', function(data) {
    console.log(data); 
});

或将子进程的标准输出输出到主标准输出。

coffeeProcess.stdout.pipe(process.stdout);

或者使用衍生继承stdio

spawn('coffee -cw my_file.coffee', { stdio: 'inherit' });

其他回答

不要使用exec。使用spawn,这是一个eventemitter对象。然后你可以在stdout/stderr事件发生时监听它们(spawn.stdout.on('data',callback..))。

来自NodeJS文档:

var spawn = require('child_process').spawn,
    ls    = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', function (data) {
  console.log('stdout: ' + data.toString());
});

ls.stderr.on('data', function (data) {
  console.log('stderr: ' + data.toString());
});

ls.on('exit', function (code) {
  console.log('child process exited with code ' + code.toString());
});

Exec缓冲输出,通常在命令执行完成时返回。

我只是想添加一个小问题,从控制台.log()输出一个派生进程的缓冲字符串,它添加了换行,这可以将派生进程的输出扩展到其他行。如果你用process.stdout.write()而不是console.log()输出stdout或stderr,那么你将从衍生进程“原貌”获得控制台输出。

我看到了这个解: Node.js:打印到控制台没有末尾换行符?

希望这对使用上述解决方案的人有所帮助(对于实时输出来说,这是一个很好的解决方案,即使它来自文档)。

exec还将返回一个ChildProcess对象,它是一个EventEmitter对象。

var exec = require('child_process').exec;
var coffeeProcess = exec('coffee -cw my_file.coffee');

coffeeProcess.stdout.on('data', function(data) {
    console.log(data); 
});

或将子进程的标准输出输出到主标准输出。

coffeeProcess.stdout.pipe(process.stdout);

或者使用衍生继承stdio

spawn('coffee -cw my_file.coffee', { stdio: 'inherit' });

受到Nathanael Smith的回答和Eric Freese评论的启发,这个问题可以简单到:

var exec = require('child_process').exec;
exec('coffee -cw my_file.coffee').stdout.pipe(process.stdout);

在回顾了所有其他答案后,我得出了以下结论:

function oldSchoolMakeBuild(cb) {
    var makeProcess = exec('make -C ./oldSchoolMakeBuild',
         function (error, stdout, stderr) {
             stderr && console.error(stderr);
             cb(error);
        });
    makeProcess.stdout.on('data', function(data) {
        process.stdout.write('oldSchoolMakeBuild: '+ data);
    });
}

有时数据是多行,因此oldSchoolMakeBuild标头将为多行出现一次。但这并没有困扰到我去改变它。