在perl @ARGV中查找管道和重定向

Deb*_*nix 3 perl pipe diamond-operator argv

编写传统的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();
}
Run Code Online (Sandbox Code Playgroud)

一些输出运行显示<>工作,但没有参数我们等待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]
$
Run Code Online (Sandbox Code Playgroud)

首先想到的是测试$#ARGV,其中包含@ARGV中最后一个参数的编号.然后我在while循环之前添加了一个测试到上面的脚本,如下所示:

if ( $#ARGV < 0 ) {   # initiated to -1 by perl
    usage();
}
Run Code Online (Sandbox Code Playgroud)

这没有产生预期的结果.对于命令行上的重定向和管道,$#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
Run Code Online (Sandbox Code Playgroud)

是否有更好的测试来查找shell传递给perl的所有命令行参数?

Ole*_*liv 5

您可以使用文件测试运算符-t来检查文件句柄STDIN是否对TTY开放.

因此,如果它对终端开放并且没有参数,那么您将显示使用文本.

if ( -t STDIN and not @ARGV ) {
    # print usage and exit
}
Run Code Online (Sandbox Code Playgroud)

  • 别客气.除了从@ARGV读取参数之外,我认为你不能访问命令行. (2认同)