如何在不使用select的情况下检查(查看)Perl中的管道数据的STDIN?

时间:2009-02-06 03:39:36

标签: perl pipe cross-platform stdin perl-select

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

不幸的是,select()无法移植到某些非POSIX系统。 还有另一种方法可以实现最大的可移植性吗?

2 个答案:

答案 0 :(得分: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和使用Perl 5.8.8的Linux可以正常工作,因此它应该可以在最常见的Perl环境中移植。

正如其他人所提到的那样,select不是一个可靠的选择,因为有时您可能正在阅读某个流程,但该流程尚未开始编写。

一切顺利,

答案 1 :(得分:5)

use POSIX 'isatty';
if ( ! @ARGV && isatty(*STDIN) ) {
    die "usage: ...";
}

请参阅:http://www.opengroup.org/onlinepubs/009695399/functions/isatty.html

请注意,select无论如何都不会有太大帮助,因为它会产生错误的结果 如果管道信息尚未准备好。例如:

seq 100000|grep 99999|perl -we'$rin="";vec($rin,fileno(STDIN),1)=1;print 0+select($rin,"","",.01)'