2016-08-08 10 views
0

Node.jsのreadlineモジュールを使用してユーザーからの情報をキャプチャしてキャプチャするCLIのテストを作成しようとしています。 stdout。私が直面している問題の簡単なバージョンは以下のとおりです。readline.write()がstdoutに到着しない

app.js:

#!/usr/bin/env node 

const readline = require('readline') 
const rl = readline.createInterface({ 
    input: process.stdin, 
    output: process.stdout 
}) 

rl.write('hello\n') 
process.exit() 

runner.js:runner.jsを実行している

const spawn = require('child_process').spawn 

const rl = spawn(__dirname + '/app.js') 

rl.stdout.on('data', chunk => { 
    console.log('stdout says', chunk.toString()) 
}) 

は、私が出力stdout says helloが、何も印刷を見ることを期待します。

ただし、app.jsを直接実行すると、helloがコンソールに表示されます。さらに、questionのような他のreadlineメソッドを使用すると、ハンドラは予期されたデータで起動します。

なぜこのコードは期待どおりに機能しませんか?どのように仕事に変えることができますか? readlineのインタフェースのインスタンスを作成する際に、「端末」として真定義:

答えて

1

()は、一つの解決策であるrl.writeの出力をキャプチャするReadline output to file Node.js

に関する。

サンプルコード:

const readline = require('readline'); 
const rl = readline.createInterface({ 
    input: process.stdin, 
    output: process.stdout, 
    terminal: true 
}); 

説明: "端末" が真である場合 readlineのモジュールのNode.jsにのみ "出力" ストリームにデータを書き込みます。それ以外の場合は、単に "行"イベントを送出し、行イベントハンドラにデータを送ります。ソースコード(https://github.com/nodejs/node/blob/master/lib/readline.js):

まず、「端末」が設定されているかどうかを確認します。そうでない場合、出力ストリームのisTTYプロパティにそれが等しくする:rl.write()関数が呼び出されたときに

if (terminal === undefined && !(output === null || output === undefined)) { 
    terminal = !!output.isTTY; 
} 
... 
this.terminal = !!terminal; 

第二に、それは「端末」は真であるかどうかに応じて、_ttyWrite()または_normalWrite()を呼び出します。 :

Interface.prototype.write = function(d, key) { 
    ... 
    this.terminal ? this._ttyWrite(d, key) : this._normalWrite(d); 
}; 

最後に、_ttyWrite()が呼び出されると、データが出力ストリームに送信されます。 _normalWrite()が呼び出された場合、出力ストリームは無視される:

//Interface.prototype._ttyWrite will invoke Interface.prototype._insertString, which will call Interface.prototype._writeToOutput 
Interface.prototype._writeToOutput = function _writeToOutput(stringToWrite) { 
    ... 
    if (this.output !== null && this.output !== undefined) 
    this.output.write(stringToWrite); 
}; 

をしたがって、app.js直接コンソールで実行される場合、「ハロー」process.stdout.isTTYに等しい「端末」として、印刷されますこれは本当です。ただし、子プロセスで実行された場合、 "terminal"はfalseになります(設定されていない場合)。process.stdout.isTTYは未定義です。

+0

このソリューションは機能しますが、なぜですか? readlineインタフェースはすでにstdoutに接続されており、その出力は端末ではなく 'data'ハンドラによって読み込まれています。 – user6689821

+0

@ user6689821、解答に今説明が追加されました:) – shaochuancs

+0

ありがとう@shaochuancs。私はまだ 'write'がデフォルトで出力ストリームを無視するのはなぜか混乱しています(なぜ書くのではなく書くのはなぜですか?)が、コードを見ていただきありがとうございます。 – user6689821

関連する問題