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

标签 perl pipe argv diamond-operator

在编写传统的 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

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

最佳答案

您可以使用file test operator -t检查文件句柄 STDIN 是否对 TTY 打开。

因此,如果它向终端打开并且没有参数,那么您将显示用法文本。

if ( -t STDIN and not @ARGV ) {
    # print usage and exit
}

关于perl - 在 perl @ARGV 中查找管道和重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7454862/

相关文章:

perl - 如何在Perl中读写管道?

c++ - C/C++ 事件驱动监控非子程序的终止

c - 用最大输入填充 C 中的 argv[1]

C 程序段错误 main()

c - 迭代 C 中的输入 char 参数?

python - 与 Perl 和 Python 相比,正则表达式模式在 TCL 中的行为有所不同

mysql - Perl mysql mac地址错误

bash - 在管道命令中从文件内容切换到 STDIN? (Linux shell )

ruby - Tcl 是否具有 PE​​RL 和 Ruby backtic 的等价物

PERL 如何跳过 while 循环中的错误