Я пишу исполняемый Perl-скрипт, назовем его SCRIPT, который принимает выходные данные другой команды, выполняемой из командной строки, и что-то делает с этими выводами.
Например
$ diff файлA файлB | СЦЕНАРИЙ
Но если я вызываю SCRIPT, не помещая его после канала, я хочу сигнализировать об ошибке.
Следующий MWE работает правильно, но я не уверен, что понимаю, почему.
#!/usr/bin/perl
use strict;
use warnings;
if ( -t STDIN )
{
print "NOTHING PIPED IN\n";
}
else
{
while ( my $line = <STDIN> )
{
print ">> " . $line;
}
}
1;
Я не могу найти документацию о том, что делает -t
. Я имею в виду, что могу обнаружить, что он проверяет, открыт ли Filehandle для терминала. Но я не уверен, что это значит. Я также не понимаю, почему я должен использовать STDIN
без оператора угла.
Другими словами,
if ( -t <STDIN> )
либо зависает, если не на принимающем конце канала, либо я теряю первую строку передаваемых данных. (То, что я теряю первую строку передаваемых данных, на самом деле имеет для меня смысл.)
Я ожидал чего-то другого. Я ожидал, что мне придется написать код следующим образом:
#!/usr/bin/perl
use strict;
use warnings;
if ( -t STDIN )
{
while ( my $line = <STDIN> )
{
print ">> " . $line;
}
}
else
{
print "NOTHING PIPED IN\n";
}
1;
-t STDIN
на самом деле тестирование с точки зрения непрофессионала.<STDIN>
в цикле while
?@ТимРобертс, ок. Это немного помогает. Почему я могу протестировать его без оператора угла?
Не то, что вы спросили, но: если вы действительно хотите проверить, является ли STDIN
трубкой, вы можете сказать -p STDIN
. Обратите внимание: если вы перенаправите файл в свой скрипт, -p STDIN
будет ложным, а ! -t STDIN
будет истинным.
<STDIN>
— сокращение от readline( STDIN )
. Вы не хотите читать ни строчки; вы хотите проверить, подключен ли дескриптор файла к терминалу.
tty — это терминал.[1] В unix tty — это особый класс символьных устройств. (Подробнее об этом позже.) По сути, это относится к интерактивному интерфейсу с пользователем.[2]
-t
, задокументировано как функция -X , тесты — это предоставленный дескриптор файла, подключенный к tty. Например, он может в конечном итоге вызвать внутренний вызов isatty.
Ранее я говорил, что tty — это особый класс символьных устройств. Это означает, что некоторые символьные устройства не являются tty. Но что более важно, это также означает, что дескрипторы файлов, которые не являются символьными устройствами, также не могут быть tty. Другие типы дескрипторов файлов включают «обычный файл», каталог, сокет, канал и блочное устройство. -t
вернет false для дескриптора, подключенного к любому из них.
$ printf '' >file
$ perl -Mv5.14 -e'say -t STDIN ? 1 : 0' # Happens to be a tty.
1
$ perl -Mv5.14 -e'say -t STDIN ? 1 : 0' </dev/tty # Definitely a tty.
1
$ perl -Mv5.14 -e'say -t STDIN ? 1 : 0' </dev/null # Char dev that's not a TTY
0
$ perl -Mv5.14 -e'say -t STDIN ? 1 : 0' <file # Plain file.
0
$ printf '' | perl -Mv5.14 -e'say -t STDIN ? 1 : 0' # Pipe
0
Эти примеры чрезвычайно наглядны и полезны. Спасибо.
Флаг
-t
спрашивает: «Этот файл подключен к терминалу?» Если вы ничего не передавали по конвейеру, то стандартный ввод будет читаться с вашего терминала.