Подтвердить что ты не робот

Как определить, выполняется ли 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?
4b9b3361

Ответ 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
}