3

従来の 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 に渡されるすべてのコマンド ライン パラメータを見つけるためのより良いテストはありますか?

4

2 に答える 2

5

ファイル テスト演算子 -tを使用して、ファイル ハンドル STDIN が TTY に対して開いているかどうかを確認できます。

したがって、端末に対して開かれていて引数がない場合は、使用法テキストを表示します。

if ( -t STDIN and not @ARGV ) {
    # print usage and exit
}
于 2011-09-17T13:06:25.763 に答える
0

-t 演算子を使用して、パイプまたはシェルのリダイレクトを使用するときに STDIN が tty に接続されているかどうかを確認すると、false が返されるため、

if ( -t STDIN and not @ARGV ){ exit Usage(); }
于 2011-09-17T13:57:15.403 に答える