如果没有传入参数并且标准输入中也没有输入,我该如何判断?

3
我正在写一个 Perl 脚本,希望在未接收到输入时显示帮助信息。
如何判断标准输入(stdin)中是否没有输入任何内容?

2
“nothing is coming in”这个说法并不是百分之百清晰。如果我运行你的脚本,然后5分钟内什么都不输入,这算吗?如果10分钟后我开始输入呢? - Keith Thompson
5个回答

8
if (@ARGV == 0 && -t STDIN && -t STDERR) { 
    print STDERR "$0: WARNING: reading input from keyboard, type ^D for EOF, ^C to intr.\n";
}

该习语可在维护和记录的模块中使用:http://p3rl.org/IO::Interactive#is_interactive()。 - daxim
3
@daxim: 哼!你过分诋毁我在Perl编程技能方面的能力,这看起来很愚蠢。再说了,大多数人何时是正确的呢?羊永远是羊,即使它们被引向悬崖边。每个具备基本技能的程序员都知道支持实际理解他们所使用的语言的参数,更不用说能够在任何地方工作的东西了。你所使用的并非在任何地方都有效,只会让人困惑。让他们先学习真正的Perl,然后再深入研究,因为否则他们将无法维护其他人的代码 - tchrist
2
@daxim:每个中级技能的程序员都知道在有足够功能需要抽象化时使用模块的优点。坦白地说,在这种情况下,你过度模块化了(让我们称之为Java综合症或过度设计)。 - ninjalj
在这些有限的文本框中争论并不好玩。我将不得不放弃我写的大部分内容,只留下一个回应:你发现了一个遗漏?那很好!提交工单。在下一个版本中,我的使用IO::Interactive的代码将变得更好,而无需我动手,而你使用原始基元的代码则不会。抽象和专业化不是很棒吗? - daxim
1
这里再次强调一下,我认为@daxim提到该模块并没有错。他当然没有用一种应得的方式来表达原始评论,因此你的回应是不必要的。当然,在这个特定的问题中,对于如此微不足道的事情,它并不是最好的解决方案,但我遇到过一些问题,纯Perl的答案并不适合我的情况,而提到相关模块的评论正好符合我的需求。 - skippr
显示剩余3条评论

0

3
$#ARGV 包含 @ARGV 的最后一个元素的索引,也就是说,参数数量减一。 - mob

0

如果你在谈论来自 STDIN 的输入,你可以检查变量是否等于空字符串(在删除 CR/LF 后)。例如:

my $myInput = <STDIN>;
chomp($myInput);
if ($myInput eq "")
{
    print "Error! You didn't submit any data!\n";
}

然而,正如@thnee所说,如果您正在检查通过命令行传递的参数,则应使用$#ARGV。

例如:

if ($#ARGV == -1)
{
    print "Error! No input arguments entered!\n";
    exit(-1);
}

参考资料:

http://perldoc.perl.org/functions/chomp.html

http://perldoc.perl.org/perlvar.html


3
thnee 提到了 $#ARGV。此外,你应该避免使用“上面”(或“下面”)等指代其他答案,因为得分相同的答案会以随机顺序出现。相反,应添加引用答案的链接。 - erickson
测试 $myInput eq "" 可以告诉您输入是否为空行,但并不能确定是否没有输入(这取决于 OP 对“没有输入”的具体解释)。 - Keith Thompson

0

如果脚本从键盘的标准输入运行,直到用户开始输入内容之前,是不会有任何可用的输入的。 - Keith Thompson

0

可以通过非阻塞读取、选择(select)或IOCTL FIONREAD来检查是否有内容从标准输入流(STDIN)进入,但是无法检查内容是否正在从标准输入流(stdin)进入,因为这还没有发生。

暂且不谈不可能性,您在要求打破惯例。例如,考虑cat、perl、sort等等。如果您不提供参数,它们会愉快地在标准输入流(STDIN)上等待直到您提供所需内容。

用户知道使用man tool或tool --help获取信息。


你觉得 ioctl(STDIN, $FIONREAD=0x4004667F, $long=pack(L=>0)) 会让他们陷入麻烦吗? :) - tchrist
@tchrist,我不知道那是什么。那是第三种查看数据是否可用的方式吗? - ikegami
是的,这是如何查看该描述符上有多少未读字节。但您必须正确获取系统的ioctl编号,然后对其返回的任何字节使用未缓冲和未编码的原始sysread。您不能将其与stdio调用混合使用,因为它仅检查挂起的内核缓冲区,而不是已发送到用户空间的任何内容。 FIONREAD是“待读取的未读字节数”的ioctl。请参见Stevens。这是那些答案属于“您真的不想知道”的问题之一。 - tchrist
@tchrist,我会把它加入列表中,但这并不改变我的答案。 - ikegami
不,当然不是。这就是为什么我加了笑脸符号的原因。您可以使用此类内容来决定是否以非规范模式读取键盘输入。 - tchrist
@tchrist,当您使用select与写入器一起使用时,您会使用类似的东西,因为select不会告诉您可以在不阻塞的情况下写入多少字节。 - ikegami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接