Как определить, выполняется ли Node.js script через трубу оболочки?
Мой вопрос похож на этот: Как определить, работает ли моя оболочка script через трубку?. Разница в том, что оболочка script Im, работающая над, записывается в Node.js.
Позволяет сказать:
echo "foo bar" | ./test.js
Тогда как я могу получить значение "foo bar"
в test.js
?
Ive читает Unix и Node: Pipes and Streams, но это похоже только на асинхронное решение (за исключением Im mistaken). Я ищу синхронное решение. Кроме того, с помощью этой методики, не кажется очень простым обнаружить, что канал script подан или нет.
TL; DR Мой вопрос двоякий:
- Как определить, выполняется ли Node.js script через трубку оболочки, например.
echo "foo bar" | ./test.js
?
- Если да, то как считывать значение канала в Node.js?
Ответы
Ответ 1
Трубы предназначены для обработки небольших входов, таких как "foo bar", но также и больших файлов.
API потока гарантирует, что вы сможете начать обработку данных, не дожидаясь полного прохождения огромного файла (это лучше для скорости и памяти). То, как это происходит, - это предоставить вам фрагменты данных.
Синхронный API для труб отсутствует. Если вы действительно хотите, чтобы весь входящий в комплект входной сигнал был в руках, прежде чем что-то делать, вы можете использовать
note: используйте только 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
Ответ 2
Я просто выяснил более простой ответ на часть моего вопроса.
Чтобы быстро и синхронно определить, передается ли содержимое конвейера в текущий script в Node.js, используйте process.stdin.isTTY
boolean:
$ node -p -e 'process.stdin.isTTY'
true
$ echo 'foo' | node -p -e 'process.stdin.isTTY'
undefined
Итак, в script вы можете сделать что-то вроде этого:
if (process.stdin.isTTY) {
// handle shell arguments
} else {
// handle piped content (see Jerome’s answer)
}
Я не нашел этого раньше, потому что я смотрел документацию для process
, где isTTY
вообще не упоминается. Вместо этого он упоминается в документации TTY.
Ответ 3
Если вам нужно подключиться к nodejs с помощью строки inline --eval в bash, cat
тоже работает:
$ echo "Hello" | node -e "console.log(process.argv[1]+' pipe');" "$(cat)"
# "Hello pipe"
Ответ 4
Вам нужно проверить stdout
(не stdin
как предложено в другом месте) следующим образом:
if (process.stdout.isTTY) {
// not piped
} else {
// piped
}