When writing a traditional Unix/Linux program perl provides the diamond operator <>. I’m trying to understand how to test if there are no argument passed at all to avoid the perl script sitting in a wait loop for STDIN when it should not.
#!/usr/bin/perl
# Reading @ARGV when pipe or redirect on the command line
use warnings;
use strict;
while ( defined (my $line = <ARGV>)) {
print "$ARGV: $. $line" if ($line =~ /eof/) ; # an example
close(ARGV) if eof;
}
sub usage {
print << "END_USAGE" ;
Usage:
$0 file
$0 < file
cat file | $0
END_USAGE
exit();
}
A few outputs runs shows that the <> works, but with no arguments we are hold in wait for STDIN input, which is not what I want.
$ cat grab.pl | ./grab.pl
-: 7 print "$ARGV: $. $line" if ($line =~ /eof/) ; # an example
-: 8 close(ARGV) if eof;
$ ./grab.pl < grab.pl
-: 7 print "$ARGV: $. $line" if ($line =~ /eof/) ; # an example
-: 8 close(ARGV) if eof;
$ ./grab.pl grab.pl
grab.pl: 7 print "$ARGV: $. $line" if ($line =~ /eof/) ; # an example
grab.pl: 8 close(ARGV) if eof;
$ ./grab.pl
^C
$ ./grab.pl
[Ctrl-D]
$
First thought is to test $#ARGV which holds the number of the last argument in @ARGV. Then I added a test to above script, before the while loop like so:
if ( $#ARGV < 0 ) { # initiated to -1 by perl
usage();
}
This did not produced the desired results. $#ARGV is -1 for the redirect and pipe on the command line. Running with this check (grabchk.pl) the problem changed and I can’t read the file content by the <> in the pipe or redirect cases.
$ ./grabchk.pl grab.pl
grab.pl: 7 print "$ARGV: $. $line" if ($line =~ /eof/) ;
grab.pl: 8 close(ARGV) if eof;
$ ./grabchk.pl < grab.pl
Usage:
./grabchk.pl file
./grabchk.pl < file
cat file | ./grabchk.pl
$ cat grab.pl | ./grabchk.pl
Usage:
./grabchk.pl file
./grabchk.pl < file
cat file | ./grabchk.pl
Is there a better test to find all the command line parameters passed to perl by the shell?
You can use file test operator -t to check if the file handle STDIN is open to a TTY.
So if it is open to a terminal and there are no arguments then you display the usage text.