下面的代码是perl程序的框架,用于处理具有结构化文本的某些文件。如果通过STDIN提供输入,该程序将按预期工作:
./process_files.pl < some_file
但是如果要处理的文件是命令行参数,它将挂起:
./process_files.pl some_file
在strace下运行此命令表明,读取文件后,程序卡在了read(0, ...)
上。可以肯定的是,在终端上输入Ctrl-D可以解开程序,然后程序运行完成。
为什么从非空@ARGV读取后,perl为什么要在STDIN上等待?
perl代码:
#!/usr/bin/perl
sub meta
{
while ( <> )
{
return if m!</META>!;
# process metadata line
}
}
sub data
{
while ( <> )
{
return if m!</DATA>!;
# process data line
}
}
while ( <> )
{
meta if m!<META>!;
data if m!<DATA>!;
}
# post processing here
exit 0;
附录:正在处理的文本文件的行具有以下模式:
lines (ignored)
<META>
meta data lines (processed)
</META>
lines (ignored)
<DATA>
data lines (processed)
</DATA>
optional lines (ignored)
答案 0 :(得分:4)
问题是您在ARGV
返回EOF后一直读取该信息。
从ARGV
进行读取会在打开@ARGV
时将其删除,因此@ARGV
在第二次查询时就为空,从而导致从STDIN读取数据。
您的程序归结为以下内容:
print "\@ARGV: @ARGV\n"; # Outputs: @ARGV: file.txt
while (<>) { } # Reads from file.txt.
print "\@ARGV: @ARGV\n"; # Outputs: @ARGV:
while (<>) { } # Reads from STDIN.
顺便说一句,您永远不要期望返回EOF的文件句柄继续返回EOF。这并非总是如此。例如,POSIX系统上的终端句柄并非如此。