Специальный файловый дескриптор ARGV
сделает это по умолчанию. Это также дескриптор, используемый readline (он же операторы <>
и <<>>
), когда ему не дан дескриптор. Так что это довольно часто встречается в скриптах Perl.
#!/usr/bin/env perl
use 5.022;
use warnings;
while (my $line = <<>>) {
# $line from one of the filenames passed as an argument, otherwise STDIN
# $ARGV is the current filename, or - when reading from STDIN
}
Вместо этого вы можете использовать оператор <>
для поддержки более старых версий Perl, но оператор <<>>
, добавленный в Perl 5.22 , является лучшим вариантом для этой задачи, если он доступен, поскольку стандартный <>
оператор позволяет передавать странные вещи, такие как date|
, чтобы запускать процессы, а не читать файлы.
Для более безопасной работы только с именами файлов при поддержке более старых версий Perl вы можете использовать ARGV :: readonly или эмулировать оператор <<>>
, как показано ниже:
#!/usr/bin/env perl
use strict;
use warnings;
unshift @ARGV, '-' unless @ARGV;
while (my $file = shift) {
my $fh;
if ($file eq '-') {
$fh = \*STDIN;
} else {
open $fh, '<', $file or die "open $file failed: $!";
}
while (my $line = <$fh>) {
# ...
}
}
(Технически, оператор <<>>
также не разрешает передавать -
в качестве аргумента для чтения STDIN, но это ваш выбор, если вы хотите это разрешить.)