<> висит на STDIN после прочтения непустого @ARGV - PullRequest
0 голосов
/ 11 января 2019

Приведенный ниже код является каркасом Perl-программы для обработки некоторых файлов со структурированным текстом. Программа работает должным образом, если ввод осуществляется через STDIN:

./process_files.pl < some_file

Но он зависает, если обрабатываемый файл является аргументом командной строки:

./process_files.pl some_file

Запуск этого режима показал, что после чтения файла программа зависла на read(0, ...). И, конечно же, набрав Ctrl-D на терминале, вы отклеиваете программу, и она запускается до конца.

Почему Perl ожидает на STDIN после чтения из непустого @ARGV?

Код Perl:

#!/usr/bin/perl

sub meta
{
    while ( <> )
    {
        return if m!</META>!;
        # process metadata line
    }
}

sub data
{
    while ( <> )
    {
        return if m!</DATA>!;
        # process data line
    }
}

while ( <> )
{
    meta if m!<META>!;
    data if m!<DATA>!;
}

# post processing here

exit 0;

ADDENDUM: строки обрабатываемого текстового файла имеют следующий шаблон:

lines (ignored)
<META>
meta data lines (processed)
</META>
lines (ignored)
<DATA>
data lines (processed)
</DATA>
optional lines (ignored)

1 Ответ

0 голосов
/ 11 января 2019

Проблема в том, что вы продолжали читать с ARGV после того, как он вернул EOF.

Чтение из ARGV удаляет записи из @ARGV по мере их открытия, поэтому @ARGV был пуст при втором цикле, в результате чего чтение считывалось из STDIN.

Ваша программа сводится к следующему:

print "\@ARGV: @ARGV\n";     # Outputs: @ARGV: file.txt
while (<>) { }               # Reads from file.txt.
print "\@ARGV: @ARGV\n";     # Outputs: @ARGV:
while (<>) { }               # Reads from STDIN.

Кстати, вы никогда не должны ожидать, что дескриптор файла, который возвращал EOF, будет продолжать возвращать EOF. Это не всегда так. Например, это не относится к дескрипторам терминалов в системах POSIX.

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