2013-03-17 12 views
20

私の質問はこれと似ています:How to detect if my shell script is running through a pipe?。違いは、私が作業しているシェルスクリプトはNode.jsで書かれていることです。Node.jsスクリプトがシェルパイプ経由で実行されているかどうかを検出する方法は?

はのは、私が入力したとしましょう:

echo "foo bar" | ./test.js 

次に、どのように私はtest.jsに値"foo bar"を得ることができますか?

私はUnix and Node: Pipes and Streamsを読んだことがありますが、それは非同期の解決方法を提供するように見えます(間違いない限り)。私は同期ソリューションを探しています。また、この手法では、スクリプトがパイプされているかどうかを検出するのは簡単ではないようです。

TL; DRは、私の質問は二つある:

  1. Node.jsのスクリプトは、例えば、シェルのパイプを通して実行されているかどうかを検出する方法echo "foo bar" | ./test.js
  2. もしそうなら、Node.jsのパイプされた値を読み取る方法は?

答えて

19

パイプは "foo bar"のような小さな入力だけでなく、巨大なファイルも扱うように作られています。

ストリームAPIを使用すると、巨大なファイルが完全にパイプスルーされるのを待たずにデータを処理できるようになります(これは速度&の方が優れています)。それを行う方法は、あなたにデータのチャンクを与えることです。

パイプ用の同期APIはありません。あなたが本当に全体が何かを行う前に、あなたの手の中に入力をパイプしたい場合は、

ノートを使用することができますのみnode >= 0.10.0を使用する例が

とストリーム2のAPIに

var data = ''; 
function withPipe(data) { 
    console.log('content was piped'); 
    console.log(data.trim()); 
} 
function withoutPipe() { 
    console.log('no content was piped'); 
} 

var self = process.stdin; 
self.on('readable', function() { 
    var chunk = this.read(); 
    if (chunk === null) { 
     withoutPipe(); 
    } else { 
     data += chunk; 
    } 
}); 
self.on('end', function() { 
    withPipe(data); 
}); 

テストを使用しているため、

echo "foo bar" | node test.js 

node test.js 
38

私はちょうど私の質問の一部に簡単な答えを見つけました。

$ node -p -e 'process.stdin.isTTY' 
true 
$ echo 'foo' | node -p -e 'process.stdin.isTTY' 
undefined 

ので、スクリプトでは、あなたがこのような何かを行うことができます:

は、迅速かつ同期パイプコンテンツはNode.jsの中に、現在のスクリプトに渡されている場合、process.stdin.isTTYブール値を使用し検出するために、

if (process.stdin.isTTY) { 
    // handle shell arguments 
} else { 
    // handle piped content (see Jerome’s answer) 
} 

私はisTTYは全く言及されていないprocessのドキュメント、見ていたので、私は前にこれを見つけられませんでした理由があります。代わりに、the TTY documentationに記載されています。

+0

残念ながら、これは子プロセスでは失敗します: 'node -p -e" require( 'child_process')exec(\ "node -p -e 'process.stdin.isTTY' \"、(err 、res)=> console.log( 'err:'、err、 'res:'、res)) '' – maxlath

1

あなたはbashでインライン--eval文字列を使用してnodejsにパイプに必要がある場合は、catあまりにも動作します:

$ echo "Hello" | node -e "console.log(process.argv[1]+' pipe');" "$(cat)" 
# "Hello pipe" 
0

あなたはこのように(などは他の場所で示唆されていないstdinstdoutをチェックする必要があります。

if (process.stdout.isTTY) { 
    // not piped 
} else { 
    // piped 
} 
関連する問題