web-dev-qa-db-ja.com

exec:標準出力「ライブ」を表示

私はこの簡単なスクリプトを持っています:

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

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

ここで、コマンドを実行してコーヒースクリプトファイルをコンパイルします。ただし、コマンドは終了しないため(コーヒーの-wオプションがあるため)、stdoutはコンソールに表示されません。コンソールから直接コマンドを実行すると、次のようなメッセージが表示されます。

18:05:59 - compiled my_file.coffee

私の質問は:node.js execでこれらのメッセージを表示することは可能ですか?はいの場合はどうですか? !

ありがとう

146
TrexXx

execを使用しないでください。 spawnオブジェクトである EventEmmiter を使用します。その後、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は出力をバッファリングし、通常、コマンドの実行が終了したときにそれを返します。

225
Pooria Azimi

execは、EventEmitterであるChildProcessオブジェクトも返します。

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

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

またはpipeは、メインプロセスの子プロセスの標準出力です。

coffeeProcess.stdout.pipe(process.stdout);

または、spawnを使用してstdioを継承します

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

すでにいくつかの答えがありますが、spawn{ stdio: 'inherit' }オプション を使用する最良の(そして最も簡単な)方法を言及しているものはありません。たとえば、git cloneからの進捗情報を表示する場合、最も正確な出力を生成するようです。

これを行うだけです:

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

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

これを このコメント で指摘してくれた@MorganTouvereyQuillingに感謝します。

40
Livven

console.log()で生成されたプロセスからバッファ文字列を出力する際の小さな問題の1つを追加したいのは、生成されたプロセスの出力を追加の行に広げることができる改行を追加することです。 process.stdout.write()の代わりにconsole.log()stdoutまたはstderrを出力すると、生成されたプロセスからコンソール出力が「そのまま」取得されます。

私はここでその解決策を見ました: Node.js:末尾の改行なしでコンソールに印刷しますか?

上記のソリューションを使用している人に役立つことを願っています(ドキュメントからのものであっても、ライブ出力に最適です)。

21
Kevin Teljeur

ナタナエル・スミスの答えとエリック・フリーズのコメントに触発されて、それは次のように簡単かもしれません:

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

これを行うユーティリティにカスタムexecスクリプトを追加すると便利です。

utilities.js

const { exec } = require('child_process')

module.exports.exec = (command) => {
  const process = exec(command)

  process.stdout.on('data', (data) => {
    console.log('stdout: ' + data.toString())
  })

  process.stderr.on('data', (data) => {
    console.log('stderr: ' + data.toString())
  })

  process.on('exit', (code) => {
    console.log('child process exited with code ' + code.toString())
  })
}

app.js

const { exec } = require('./utilities.js')

exec('coffee -cw my_file.coffee')
7
IanLancaster

他のすべての答えを確認した後、私はこれで終わった:

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

dataは複数行になる場合があるため、oldSchoolMakeBuildヘッダーは複数行に1回表示されます。しかし、これはそれを変えるほど私を悩ませませんでした。

4
Tongfa

child_process.spawnは、stdoutおよびstderrストリームを持つオブジェクトを返します。 stdoutストリームをタップして、子プロセスがNodeに送り返すデータを読み取ることができます。ストリームであるstdoutには、「データ」、「終了」、およびストリームが持つその他のイベントがあります。 spawnは、子プロセスがNodeに大量のデータを返すようにする場合に最適です-画像処理、バイナリデータの読み取りなど。

以下のようにchild_process.spawnを使用して問題を解決できます。

var spawn = require('child_process').spawn,
ls = spawn('coffee -cw my_file.coffee');

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('code ' + code.toString());
});
1