2013-03-17 18 views
20

Moje pytanie jest podobne do tego: How to detect if my shell script is running through a pipe?. Różnica polega na tym, że skrypt powłoki, nad którym pracuję, jest zapisany w pliku Node.js.Jak wykryć, czy skrypt Node.js działa przez potok powłoki?

powiedzmy wejdę:

echo "foo bar" | ./test.js 

Więc jak mogę uzyskać wartość "foo bar" w test.js?

Przeczytałem Unix and Node: Pipes and Streams, ale wydaje się, że tylko oferuje rozwiązanie asynchroniczne (chyba że się mylę). Szukam synchronicznego rozwiązania. Poza tym przy użyciu tej techniki nie jest łatwo wykryć, czy skrypt jest podłączony, czy nie.

TL; DR pytanie jest dwojaki:

  1. Jak wykryć czy skrypt node.js działa poprzez rurę powłoki, np echo "foo bar" | ./test.js?
  2. Jeśli tak, jak odczytać wartość potokową w pliku Node.js?

Odpowiedz

19

Rury są przystosowane do obsługi małych wejść, takich jak "foo bar", ale także ogromnych plików.

Strumień API gwarantuje, że możesz zacząć przetwarzać dane, nie czekając na całkowite przepuszczenie ogromnego pliku (to jest lepsze dla pamięci o szybkości &). Sposób, w jaki to robi, polega na podawaniu fragmentów danych.

Brak synchronicznego interfejsu API dla potoków. Jeśli naprawdę chcesz mieć cały rurami wejście w swoje ręce przed robi coś, można użyć

Uwaga: Należy używać tylko node >= 0.10.0 ponieważ przykład wykorzystuje API stream2

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); 
}); 

testu z

echo "foo bar" | node test.js 

i

node test.js 
38

Właśnie znalazłem prostszą odpowiedź na część mojego pytania.

Aby szybko i synchronicznie wykryć, czy rurami treść jest przekazywana do skryptu w node.js, użyj process.stdin.isTTY logiczną:

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

Więc w skrypcie, można zrobić coś takiego:

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

powodem nie znaleźliśmy tego wcześniej dlatego, że szukałem w dokumentacji process, gdzie isTTY nie wspomniano w ogóle. Zamiast tego jest wspomniany w the TTY documentation.

+0

Niestety, to się nie powiedzie w procesie potomnym: 'node -p -e" require ('child_process'). Exec (\ "node -p -e 'process.stdin.isTTY' \", (err , res) => console.log ("err:", err, "res:", res)) "' – maxlath

1

Jeśli trzeba rurę do nodejs wykorzystaniem inline --eval ciąg w bash, cat działa zbyt:

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

Trzeba sprawdzić stdout (nie stdin jak zasugerował gdzie indziej) tak:

if (process.stdout.isTTY) { 
    // not piped 
} else { 
    // piped 
} 
Powiązane problemy