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

发布于 2024-12-05 00:05:48 字数 1747 浏览 1 评论 0原文

在编写传统的 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 的所有命令行参数?

When writing a traditional Unix/Linux program perl provides the diamond operator <>. I'm trying to understand how to test if there are no argument passed at all to avoid the perl script sitting in a wait loop for STDIN when it should not.

#!/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();
}

A few outputs runs shows that the <> works, but with no arguments we are hold in wait for STDIN input, which is not what I want.

$ 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]
$

First thought is to test $#ARGV which holds the number of the last argument in @ARGV. Then I added a test to above script, before the while loop like so:

if ( $#ARGV < 0 ) {   # initiated to -1 by perl
    usage();
}

This did not produced the desired results. $#ARGV is -1 for the redirect and pipe on the command line. Running with this check (grabchk.pl) the problem changed and I can't read the file content by the <> in the pipe or redirect cases.

$ ./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

Is there a better test to find all the command line parameters passed to perl by the shell?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ㄟ。诗瑗 2024-12-12 00:05:48

您可以使用文件测试运算符-t来检查文件句柄STDIN是否对电传打字机。

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

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

You can use file test operator -t to check if the file handle STDIN is open to a TTY.

So if it is open to a terminal and there are no arguments then you display the usage text.

if ( -t STDIN and not @ARGV ) {
    # print usage and exit
}
血之狂魔 2024-12-12 00:05:48

使用 -t 运算符检查 STDIN 是否连接到 tty
当您使用管道或外壳重定向时,它将返回 false,因此您使用

if ( -t STDIN and not @ARGV ){ exit Usage(); }

use -t operator to check if STDIN is connected to a tty
when you use pipe or shell redirection, it will return false, so you use

if ( -t STDIN and not @ARGV ){ exit Usage(); }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文