私はこの簡単なスクリプトを持っています:
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でこれらのメッセージを表示することは可能ですか?はいの場合はどうですか? !
ありがとう
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
は出力をバッファリングし、通常、コマンドの実行が終了したときにそれを返します。
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' });
すでにいくつかの答えがありますが、spawn
と { stdio: 'inherit' }
オプション を使用する最良の(そして最も簡単な)方法を言及しているものはありません。たとえば、git clone
からの進捗情報を表示する場合、最も正確な出力を生成するようです。
これを行うだけです:
var spawn = require('child_process').spawn;
spawn('coffee', ['-cw', 'my_file.coffee'], { stdio: 'inherit' });
これを このコメント で指摘してくれた@MorganTouvereyQuillingに感謝します。
console.log()
で生成されたプロセスからバッファ文字列を出力する際の小さな問題の1つを追加したいのは、生成されたプロセスの出力を追加の行に広げることができる改行を追加することです。 process.stdout.write()
の代わりにconsole.log()
でstdout
またはstderr
を出力すると、生成されたプロセスからコンソール出力が「そのまま」取得されます。
私はここでその解決策を見ました: Node.js:末尾の改行なしでコンソールに印刷しますか?
上記のソリューションを使用している人に役立つことを願っています(ドキュメントからのものであっても、ライブ出力に最適です)。
ナタナエル・スミスの答えとエリック・フリーズのコメントに触発されて、それは次のように簡単かもしれません:
var exec = require('child_process').exec;
exec('coffee -cw my_file.coffee').stdout.pipe(process.stdout);
これを行うユーティリティにカスタム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')
他のすべての答えを確認した後、私はこれで終わった:
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回表示されます。しかし、これはそれを変えるほど私を悩ませませんでした。
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());
});