Как я могу проверить (посмотреть) STDIN для данных по конвейеру в Perl без использования select? - PullRequest
10 голосов
/ 06 февраля 2009

Я пытаюсь справиться с возможностью того, что никакие аргументы и данные по конвейеру не передаются в скрипт Perl. Я предполагаю, что если нет аргументов, то ввод осуществляется через STDIN. Однако если пользователь не предоставляет аргументов и ничего не передает в сценарий, он попытается получить ввод с клавиатуры. Моя цель - вместо этого предоставить сообщение об ошибке.

К сожалению, select() не является переносимым для некоторых не POSIX систем. Есть ли другой способ сделать это с максимальной переносимостью?

Ответы [ 2 ]

20 голосов
/ 06 февраля 2009

Perl поставляется с оператором проверки файлов -t, который сообщает вам, открыт ли определенный дескриптор файла для TTY. Итак, вы должны быть в состоянии сделать это:

if ( -t STDIN and not @ARGV ) {
    # We're talking to a terminal, but have no command line arguments.
    # Complain loudly.
}
else {
    # We're either reading from a file or pipe, or we have arguments in
    # @ARGV to process.
}

Быстрый тест показывает, что это прекрасно работает в Windows с Perl 5.10.0 и Linux с Perl 5.8.8, поэтому он должен быть переносимым в большинстве распространенных сред Perl.

Как уже упоминалось, select не будет надежным выбором, так как могут быть моменты, когда вы читаете из процесса, но этот процесс еще не начал писать.

Всего наилучшего,

Пол

5 голосов
/ 06 февраля 2009
use POSIX 'isatty';
if ( ! @ARGV && isatty(*STDIN) ) {
    die "usage: ...";
}

См .: http://www.opengroup.org/onlinepubs/009695399/functions/isatty.html

Обратите внимание, что выбор в любом случае не очень поможет, так как он даст ложные результаты если информация о канале еще не готова Пример:

seq 100000|grep 99999|perl -we'$rin="";vec($rin,fileno(STDIN),1)=1;print 0+select($rin,"","",.01)'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...