Perl set file handle based on command line args

270 views Asked by At

I want to read from the default input if data is piped in or a file is provided, but if nothing is given I would like to supply a default for while(<>) to execute on.

Pseudocode:

if(!<>){
  <> = system("ls | ./example.pl");
}

while(<>){
...
...
...
}
2

There are 2 answers

2
hobbs On BEST ANSWER

Your "if data is piped in" makes things difficult. It's easy to say

if (!@ARGV) {
    @ARGV = ("somedefault");
}

while (<>) {
    ...
}

which will operate on "somedefault" if no filenames are given on the commandline — but that means you'll never get the Perl default of reading from stdin if there aren't any filenames on the commandline.

One possible compromise is to use the -t operator to guess whether stdin is a terminal:

if (!@ARGV && -t STDIN) {
    @ARGV = ("somedefault");
}

Which will use "somedefault" if there are no filenames on the commandline and stdin is attached to a terminal, but it will use stdin if there are no filenames and stdin is redirected from a file or a pipe. This is a little magical (maybe annoyingly so), but does what you asked for.

0
Ether On

How about trying to read from <>, and then falling back to your default if nothing was read?

while (my $line = <>)
{
     do_stuff($line);
}

# if no lines were read, fall back to default data source
if (not $.)
{
     while (my $line = <SOMETHING_ELSE>)
     {
          do_stuff($line);
     }
}

You can read about the $. variable here, at perldoc perlop - it indicates the "current" line number of the most recent filehandle read from. If it is undefined, there was nothing to read from <>.