Reputation: 2554
The code below is the skeleton of a perl program to process some files with structured text. The program works as expected if the input is provided via STDIN:
./process_files.pl < some_file
But it hangs if the file to be processed is a command line argument:
./process_files.pl some_file
Running this under strace showed that after reading the file, the program is stuck on read(0, ...)
. And sure enough, typing Ctrl-D at the terminal unsticks the program and it then runs to completion.
Why is perl waiting on STDIN after reading from a non-empty @ARGV?
The perl code:
#!/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;
ADDENDUM: the lines of the text file being processed have this pattern:
lines (ignored)
<META>
meta data lines (processed)
</META>
lines (ignored)
<DATA>
data lines (processed)
</DATA>
optional lines (ignored)
Upvotes: 0
Views: 330
Reputation: 386551
The problem is that you kept read from ARGV
after it returned EOF.
Reading from ARGV
removes the entries from @ARGV
as it opens them, so @ARGV
was empty the second go around, causing the read to read from STDIN.
Your program boils down to the following:
print "\@ARGV: @ARGV\n"; # Outputs: @ARGV: file.txt
while (<>) { } # Reads from file.txt.
print "\@ARGV: @ARGV\n"; # Outputs: @ARGV:
while (<>) { } # Reads from STDIN.
By the way, you should never expect a file handle that returned EOF to keep returning EOF. This is not always the case. For example, it's not the case for handles to terminals on POSIX systems.
Upvotes: 4