従来の Unix/Linux プログラムを作成する場合、perl はダイアモンド演算子 <> を提供します。引数がまったく渡されないかどうかをテストして、perl スクリプトが STDIN の待機ループに入らないようにする方法を理解しようとしています。
#!/usr/bin/perl
# Reading @ARGV when pipe or redirect on the command line
use warnings;
use strict;
while ( defined (my $line = <ARGV>)) {
print "$ARGV: $. $line" if ($line =~ /eof/) ; # an example
close(ARGV) if eof;
}
sub usage {
print << "END_USAGE" ;
Usage:
$0 file
$0 < file
cat file | $0
END_USAGE
exit();
}
いくつかの出力を実行すると、 <> が機能することが示されますが、引数がない場合、STDIN 入力を待機する必要があり、これは私が望んでいるものではありません。
$ cat grab.pl | ./grab.pl
-: 7 print "$ARGV: $. $line" if ($line =~ /eof/) ; # an example
-: 8 close(ARGV) if eof;
$ ./grab.pl < grab.pl
-: 7 print "$ARGV: $. $line" if ($line =~ /eof/) ; # an example
-: 8 close(ARGV) if eof;
$ ./grab.pl grab.pl
grab.pl: 7 print "$ARGV: $. $line" if ($line =~ /eof/) ; # an example
grab.pl: 8 close(ARGV) if eof;
$ ./grab.pl
^C
$ ./grab.pl
[Ctrl-D]
$
最初に考えられるのは、@ARGV の最後の引数の番号を保持する $#ARGV をテストすることです。次に、while ループの前に、上記のスクリプトにテストを追加しました。
if ( $#ARGV < 0 ) { # initiated to -1 by perl
usage();
}
これでは、望ましい結果が得られませんでした。$#ARGV は、コマンド ラインのリダイレクトとパイプに対して -1 です。このチェック (grabchk.pl) を実行すると、問題が変わり、パイプまたはリダイレクトのケースで <> によってファイルの内容を読み取ることができません。
$ ./grabchk.pl grab.pl
grab.pl: 7 print "$ARGV: $. $line" if ($line =~ /eof/) ;
grab.pl: 8 close(ARGV) if eof;
$ ./grabchk.pl < grab.pl
Usage:
./grabchk.pl file
./grabchk.pl < file
cat file | ./grabchk.pl
$ cat grab.pl | ./grabchk.pl
Usage:
./grabchk.pl file
./grabchk.pl < file
cat file | ./grabchk.pl
シェルによって perl に渡されるすべてのコマンド ライン パラメータを見つけるためのより良いテストはありますか?