57

そのコマンドの入力と出力をリダイレクトせずに、Node.js からシェル コマンドを起動しようとしています。シェル スクリプトや Ruby のコマンドを使用してコマンドにシェルを実行するのと同じsystemです。子プロセスが STDOUT に書き込みたい場合は、コンソールに直接送信します (または、Node アプリの出力がリダイレクトされた場合はリダイレクトされます)。

ノードには、これを行う簡単な方法がないようです。別のプロセスを実行する唯一の方法は、子プロセスの入力と出力child_process常にパイプにリダイレクトする を使用することです。これらのパイプからデータを受け取り、それをプロセスの STDOUT および STDERR に書き込むコードを作成することはできますが、そうすると、API によってある程度の柔軟性が犠牲になります。

2 つの機能が必要です。

  • シェル構文。コマンド間で出力をパイプしたり、Windows バッチ ファイルを実行したりしたいと考えています。
  • 無制限の出力。私がコンパイラにシェルアウトしていて、メガバイトのコンパイラ警告を生成したい場合、ユーザーがうんざりして Ctrl + C を押すまで、それらすべてを画面上でスクロールさせたいと思います。

Node は、これら 2 つの機能のどちらかを選択するよう強制したいようです。

  • 無制限の量の出力が必要な場合は、 を使用child_process.spawnして を実行child.stdout.on('data', function(data) { process.stdout.write(data); });し、同じことをstderr. 残念ながら、spawnシェル構文はサポートされていません。
  • シェル構文が必要な場合は、child_process.exec. しかしexec、子プロセスの STDOUT と STDERR をバッファリングし、最後にそれらをすべて渡すことを主張し、それらのバッファのサイズを制限します (構成可能、デフォルトで 200K)。on('data')生成された出力を確認したい場合は、引き続きイベントをフックできますexecが、データもそのバッファーに追加します。データ量が定義済みのバッファ サイズを超えるexecと、子プロセスが終了します。

(柔軟性の観点から、両方の世界で最悪child_process.execFileの もあります。シェル構文はありませんが、期待する出力量を制限する必要があります。)

何か不足していますか?ノードの子プロセスにシェルアウトし、その入力と出力をリダイレクトしない方法はありますか? シェル スクリプトや Ruby などで利用できるように、シェル構文をサポートし、事前に定義された量の出力の後に無駄にならないものはありますか?

4

4 に答える 4

46

引数を介して stdin/out/error ストリームを継承できるspawnため、手動でパイプする必要はありません。

var spawn = require('child_process').spawn;
spawn('ls', [], { stdio: 'inherit' });

シェル構文には shell を使用します。bash の場合-c、文字列からスクリプトを読み取るためのパラメーターです。

var spawn = require('child_process').spawn;
var shellSyntaxCommand = 'ls -l | grep test | wc -c';
spawn('sh', ['-c', shellSyntaxCommand], { stdio: 'inherit' });

要約すると:

var spawn = require('child_process').spawn;
function shspawn(command) {
   spawn('sh', ['-c', command], { stdio: 'inherit' });
} 

shspawn('ls -l | grep test | wc -c');
于 2012-12-14T13:24:02.847 に答える
4

私はそれを使用していませんが、このライブラリを見たことがあります: https://github.com/polotek/procstreams

あなたがこれをするなら。プロセスの.out()stdin/out に自動的にパイプします。

var $p = require('procstreams');
$p('cat lines.txt').pipe('wc -l').out();

If はシェル構文をサポートしていませんが、それはかなり些細なことだと思います。

var command_str = "cat lines.txt | wc -l";
var cmds = command_str.split(/\s?\|\s?/);
var cmd = $p(cmds.shift());
while(cmds.length) cmd = cmd.pipe(cmds.shift());
cmd
  .out()
  .on('exit', function() {
    // Do whatever
  });
于 2012-03-19T20:39:25.253 に答える
0

child_process モジュールのノード ドキュメントに例があります。

実行時間の長いプロセスを切り離し、その出力をファイルにリダイレクトする例:

 var fs = require('fs'),
     spawn = require('child_process').spawn,
     out = fs.openSync('./out.log', 'a'),
     err = fs.openSync('./out.log', 'a');

 var child = spawn('prg', [], {
   detached: true,
   stdio: [ 'ignore', out, err ]
 });

 child.unref();
于 2013-03-15T15:50:49.950 に答える