Perl устанавливает дескриптор файла на основе аргументов командной строки - PullRequest
2 голосов
/ 27 января 2012

Я хочу прочитать из ввода по умолчанию, если данные передаются по каналу или предоставляется файл, но если ничего не дано, я хотел бы указать значение по умолчанию для while(<>) для выполнения.

Псевдокод:

if(!<>){
  <> = system("ls | ./example.pl");
}

while(<>){
...
...
...
}

Ответы [ 2 ]

5 голосов
/ 27 января 2012

Ваше "если данные передаются по каналу" усложняет ситуацию.Легко сказать

if (!@ARGV) {
    @ARGV = ("somedefault");
}

while (<>) {
    ...
}

, который будет работать на "somedefault", если в командной строке не указаны имена файлов, но это означает, что вы никогда не получите Perl по умолчанию для чтения из stdin, если их нетимена файлов в командной строке.

Одним из возможных компромиссов является использование оператора -t , чтобы угадать, является ли stdin терминалом:

if (!@ARGV && -t STDIN) {
    @ARGV = ("somedefault");
}

, который будет использовать "somedefault"если в командной строке нет имен файлов и stdin подключен к терминалу, но он будет использовать stdin, если имен файлов нет, а stdin перенаправляется из файла или канала.Это немного волшебно (может быть досадно), но делает то, что вы просили.

4 голосов
/ 27 января 2012

Как насчет попытки чтения из <>, а затем возврата к значениям по умолчанию, если ничего не было прочитано?

while (my $line = <>)
{
     do_stuff($line);
}

# if no lines were read, fall back to default data source
if (not $.)
{
     while (my $line = <SOMETHING_ELSE>)
     {
          do_stuff($line);
     }
}

О переменной $. можно прочитать здесь, на perldocperlop - указывает «текущий» номер строки самого последнего считанного дескриптора файла.Если оно не определено, читать нечего с <>.

...