在Perl中,如何确定是否存在标准输入?

时间:2010-06-04 18:02:30

标签: perl stdin

我有一个抓住标准输入的脚本:

&process_input

sub process_input {
    while(<STDIN>) {
       $log_data .= $_;
    }
}

当我运行脚本时:

myscript.pl -param1=a -param2=b

我陷入了这个子程序。如果我这样做,一切都运行正常:

echo "" | myscript.pl -param1=a -param2=b

问题是我如何确定我是否有标准品?我会认为while()会返回false并且不会运行,但我猜它实际上在等着你输入一些东西,因为它被“卡住”了。

4 个答案:

答案 0 :(得分:18)

您要做的是检查STDIN(STanDard INput)的来源:另一个应用程序或终端。在您的情况下,它是第二个选项,导致读取操作停止进程,直到用户输入内容。有关解决方案,请参阅How can I tell if STDIN is connected to a terminal in Perl?

if (-t STDIN) {
    # input attached to terminal and will probably ask user
} else {
    # input from other process
}

还有IO::Interactive可以做得更好/更可靠的检查。

答案 1 :(得分:2)

在控制台上按“Enter”之前,语句<STDIN>不会返回。如果你想解决这个问题,我相信你可以使用IO::Handle来包裹STDIN,并调用$stdin->blocking(0)来启用非阻塞IO。

答案 2 :(得分:1)

这是正常的。如果没有输入文件作为参数,则unix工具的标准用法是使用STDIN。请尝试catlessgrep等。如果只是

,则由调用者提供输入
tool < /dev/null

我强烈建议不要试图确定“输入”是否可用,因为无论你如何实现这一点,它都会引入问题。具体来说,请避免使用-t,因为在需要时伪造终端会有问题。相反,依赖于更传统的界面。

如果你想让你的工具没有输入,那么你首先要使用STDIN是很奇怪的。通常会使用可选参数。

tool --foo file
tool --foo <( echo "" )

另一个选择是请求用户在没有输入时告诉你。

tool --batch

为了帮助您解决界面的设计问题,了解工具的功能确实很有帮助。

答案 3 :(得分:0)

当用户键入文件结束符号Ctrl + D时,您的程序将继续。