В Perl, как определить, присутствует ли стандартный ввод? - PullRequest
6 голосов
/ 04 июня 2010

У меня есть скрипт, который получает стандартный ввод:

&process_input

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

Когда я запускаю скрипт:

myscript.pl -param1=a -param2=b

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

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

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

Ответы [ 4 ]

18 голосов
/ 04 июня 2010

Что вы хотите сделать, это проверить, откуда поступает ваш STDIN (STanDard INput): другое приложение или терминал. В вашем случае это второй вариант, заставляющий операцию чтения останавливать процесс, пока пользователь не введет что-то. Для решения см. Как узнать, подключен ли STDIN к терминалу в Perl? .

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

Существует также IO :: Interactive , который может выполнять более качественную / более надежную проверку.

2 голосов
/ 04 июня 2010

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

1 голос
/ 21 апреля 2011

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

tool < /dev/null

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

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

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

Другим вариантом будет запрос пользователя о том, что нет ввода.

tool --batch

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

0 голосов
/ 24 августа 2011

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

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