10

我正在尝试处理没有参数和管道数据传递给 Perl 脚本的可能性。我假设如果没有参数,那么输入将通过 STDIN 进行管道传输。但是,如果用户没有提供任何参数并且没有向脚本传递任何内容,它将尝试获取键盘输入。我的目标是提供错误消息。

不幸的是,select()它不能移植到一些非 POSIX 系统。是否有另一种方法可以最大限度地提高便携性?

4

2 回答 2

20

Perl 带有-t文件测试操作符,它告诉你一个特定的文件句柄是否对 TTY 开放。所以,你应该能够做到这一点:

if ( -t STDIN and not @ARGV ) {
    # We're talking to a terminal, but have no command line arguments.
    # Complain loudly.
}
else {
    # We're either reading from a file or pipe, or we have arguments in
    # @ARGV to process.
}

一个快速的测试表明,在 Windows 上运行 Perl 5.10.0 和 Linux 上运行 Perl 5.8.8,所以它应该可以在最常见的 Perl 环境中移植。

正如其他人所提到的,select这不是一个可靠的选择,因为有时您可能正在从进程中读取,但该进程尚未开始写入。

祝一切顺利,

保罗

于 2009-02-06T05:43:44.517 回答
5
use POSIX 'isatty';
if ( ! @ARGV && isatty(*STDIN) ) {
    die "usage: ...";
}

见:http ://www.opengroup.org/onlinepubs/009695399/functions/isatty.html

请注意,无论如何,选择不会有太大帮助,因为如果管道信息还没有准备好,它会产生错误的结果。例子:

seq 100000|grep 99999|perl -we'$rin="";vec($rin,fileno(STDIN),1)=1;print 0+select($rin,"","",.01)'
于 2009-02-06T05:03:09.323 回答