我有一个抓住标准输入的脚本:
&process_input
sub process_input {
while(<STDIN>) {
$log_data .= $_;
}
}
当我运行脚本时:
myscript.pl -param1=a -param2=b
我陷入了这个子程序。如果我这样做,一切都运行正常:
echo "" | myscript.pl -param1=a -param2=b
问题是我如何确定我是否有标准品?我会认为while()会返回false并且不会运行,但我猜它实际上在等着你输入一些东西,因为它被“卡住”了。
答案 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。请尝试cat
,less
,grep
等。如果只是
tool < /dev/null
我强烈建议不要试图确定“输入”是否可用,因为无论你如何实现这一点,它都会引入问题。具体来说,请避免使用-t
,因为在需要时伪造终端会有问题。相反,依赖于更传统的界面。
如果你想让你的工具没有输入,那么你首先要使用STDIN是很奇怪的。通常会使用可选参数。
tool --foo file
tool --foo <( echo "" )
另一个选择是请求用户在没有输入时告诉你。
tool --batch
为了帮助您解决界面的设计问题,了解工具的功能确实很有帮助。
答案 3 :(得分:0)
当用户键入文件结束符号Ctrl + D时,您的程序将继续。