2010-06-04 2 views
6

У меня есть сценарий, который захватывает стандартный ввод:В Perl, как определить, присутствует ли стандартный вход?

&process_input 

sub process_input { 
    while(<STDIN>) { 
     $log_data .= $_; 
    } 
} 

При запуске сценария:

myscript.pl -param1=a -param2=b 

Я застрять в этой подпрограмме. Все работает нормально, если я делаю:

echo "" | myscript.pl -param1=a -param2=b 

Вопрос в том, как определить, если у меня даже есть стандарт положить? Я бы подумал, что while() вернет false и не запустится, но я предполагаю, что на самом деле вас ждет, чтобы вы написали что-то в этом, почему оно «застряло».

+1

Возможный дубликат [Как узнать, подключен ли STDIN к терминалу в Perl?] (Http://stackoverflow.com/questions/528781/how-can-i-tell-if-stdin-is-connected -to-a-terminal-in-perl) – Ether

ответ

18

Что вы хотите сделать, это проверить, откуда приходит STDIN (STanDard INput): другое приложение или терминал. В вашем случае это второй вариант, в результате чего операция чтения останавливает процесс, пока пользователь ничего не вводит. Для решения см. How can I tell if STDIN is connected to a terminal in Perl?.

if (-t STDIN) { 
    # input attached to terminal and will probably ask user 
} else { 
    # input from other process 
} 

Там также IO::Interactive, которые могли бы сделать лучше/более надежную проверку.

+0

Спасибо! Поскольку скрипт также может запускаться другим приложением, я мог бы использовать параметр -t. – EDJ

2

Заявление <STDIN> не возвращается, пока вы не нажмете «enter» на консоли. Если вы хотите обойти это, я считаю, что вы можете использовать IO::Handle для обертывания STDIN и позвонить $stdin->blocking(0), чтобы включить неблокирующий ввод-вывод.

+2

Проблема не блокирует IO, но что '' (что эквивалентно 'readline (* FILEHANDLE)') ищет строку ввода. Он не вернется, пока не будет найден '\ n' (ну, технически экземпляр разделителя входных записей' $/').Неважно, блокируется ли ручка или нет. Кроме того, если вы используете 'IO :: Handle', вы можете просто использовать его методы для существующих глобальных дескрипторов:' STDIN-> blocking (0); ' – daotoad

1

Это нормально. Стандартное использование инструментов unix - это использование STDIN, если в качестве аргумента не задан входной файл. Попробуйте cat, less, grep и т.д. Это до вызывающей, чтобы обеспечить ввод, если только

tool < /dev/null 

Я настоятельно советую пытаться определить, является ли «вход» доступен как он будет создавать проблемы, независимо от того, как вы достигаете это. В частности, избегайте -t, так как проблематично подделать терминал, когда это необходимо. Вместо этого полагайтесь на более обычный интерфейс.

Если вы хотите, чтобы у вас не было доступа к вашему инструменту, странно, что вы использовали бы STDIN в первую очередь. Обычно можно использовать необязательный аргумент.

tool --foo file 
tool --foo <(echo "") 

Другой вариант - запросить, чтобы пользователь сообщал вам, когда нет ввода.

tool --batch 

Чтобы помочь вам с проблемами дизайна вашего интерфейса, это действительно поможет узнать, что делает ваш инструмент.

0

Ваша программа будет продолжаться, когда пользователь наберет Ctrl + D, конец символа файла.

Смежные вопросы