2013-03-17 126 views
20

我的問題與此相似:How to detect if my shell script is running through a pipe?。區別在於我正在使用的shell腳本是用Node.js編寫的。如何檢測Node.js腳本是否通過shell管道運行?

比方說,我進入:

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,因爲示例使用STREAM2 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.js的當前腳本,使用process.stdin.isTTY布爾:

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

因此,在腳本中,你可以做這樣的事情:

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

,因爲我一直在尋找的文檔process,其中沒有提及isTTY我沒有找到此之前,就是這個原因。相反,它在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 2017-02-19 15:54:46

1

如果需要管道進入使用bash中的直列--eval串的NodeJS,cat工程太:

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

您需要檢查stdout(不stdin像其他地方的建議)是這樣的:

if (process.stdout.isTTY) { 
    // not piped 
} else { 
    // piped 
} 
相關問題