http://qs1969.pair.com?node_id=373293


in reply to Testing <> for undefined

Okay, here's something I don't understand.

Suppose I have the following code, I'll call it prog.pl:

#!/usr/bin/perl my $lines; my @lines; print ("\@ARGV: @ARGV, \$\#ARGV: $#ARGV\n"); if (!@ARGV){ print("No command line parameters present"); } chomp(@lines = <>); foreach $lines (@lines){ print("$lines\n"); }


1. If I run the program as perl prog.pl test.txt it prints out

@ARGV: test.txt, $#ARGV: 0

2. If I run the program as perl prog.pl it prints out

@ARGV: , $#ARGV: -1

(This next one is my problem.)

3. If I run the program as perl prog.pl < test.txt it prints out

@ARGV: , $#ARGV: -1

which looks as if there were no command line arguments.

Now, I realize that in some aspects, this might be considered correct,
as there are no command line arguments, just input to the <> operator.
Will GetOpt get around this peculiarity?
Or am I going to be stuck always showing my little help text no matter what?

Am I missing something dreadfully obvious?

Replies are listed 'Best First'.
Re^2: Testing <> for undefined
by graff (Chancellor) on Jul 11, 2004 at 03:18 UTC
    When you invoke the perl interpreter (i.e. "perl") on the command line, and give it the name of a script file to load and execute, then any command-line args that follow the name of the script file are passed directly to the script as the contents of @ARGV. If nothing follows the name of the script file, then the script gets an empty @ARGV.

    If the script file itself is treated by the shell/OS as an executable file, so that the name of the script file can be the first thing on the command line, the behavior is the same: any args following the name of the script file are provided to the script in @ARGV.

    Of course, if the things that follow the script name happen to have special meaning to the shell, like a redirection operator (< or >), logic/process-control operator (& or vertical bar), or other things (depending on your shell), then the shell will do what it is supposed to do with such args before working out the strings to be passed to your script as @ARGV.

    So in a command like  myscript.pl < my.input (or the version that uses "perl" at the beginning), the angle bracket and the arg after it are treated by the shell as things to be handled by the shell, and these are not passed on to the perl script's @ARGV. This is why, if your script is set up to accept args that contain such characters, you need to quote or escape them on the command line, so that the shell will pass them to the script verbatim rather than acting on them itself.

      Ah, thank you very much.

      I hypothetically knew this, but I had never really internalized it.

      Thanks for the explanation!