pp has asked for the wisdom of the Perl Monks concerning the following question:

I am new to perl and I am tasked to do the following: I am trying to pass two values from a unix script into a perl script. In my perl script I have the following to read the values. use File::Basename; $infile_name = shift(@ARGV); And when I do a print "$infile_name" it only gives me the second value passed and omits the first one. How can I read both the values passed into this perl script? Thanks

Replies are listed 'Best First'.
Re: ARGV Usage
by derby (Abbot) on Aug 30, 2007 at 15:56 UTC

    I'd have to agree with andyford. You code is doing the correct thing from a perl perspective:

    #!/usr/bin/perl use strict; use warnings; my $infile_name = shift( @ARGV ); print $infile_name, "\n";
    when called, does:
    > ./test.pl foo.txt foo.txt
    So are you expecting test.pl to be in the @ARGV array? This is one place where perl differs from other programming languages. @ARGV is not populated with the name of the invoked program (ala C) - that's in the magic variable $0.

    -derby
Re: ARGV Usage
by dwm042 (Priest) on Aug 30, 2007 at 15:15 UTC
    @ARGV is an array, so you need to read the data as an array. One way is:

    #!/usr/bin/perl -w # # input from command line # my ( $foo, $bar ) = @ARGV; print "foo = $foo\n"; print "bar = $bar\n";
    You could also use $ARGV[0], 1, etc, and use $#ARGV to know how many arguments you have. Another way is just to use shift:
    #!/usr/bin/perl -w # # input from command line # my $foo = shift; my $bar = shift; print "foo = $foo\n"; print "bar = $bar\n";
    Now, if you're serious about command line input, I'd suggest looking at Getopt::Long. and perhaps Pod::Usage. A piece of the beginning of one of my work scripts might look like:

    #!/usr/bin/perl # # embed perdoc somewhere (top or bottom) for script documentation. # use warnings; use strict; use Getopt::Long; use Pod::Usage; my $help = 0; my $man = 0; GetOptions('help|?' => \$help, man => \$man ) or pod2usage(2); pod2usage(-exitval => 0, -verbose => 1) if $help; pod2usage(-exitval => 0, -verbose => 2) if $man; my $file = shift; pod2usage(-exitfile => 1, -verbose => 1) unless ( defined( $file )); die("File $file is not a regular file.\n") unless ( -f $file );
    Update: cleanup and typo fixes

      $#ARGV is the index of the last argument; @ARGV in scalar context is how many arguments.</small-but-crucial-distinction>

Re: ARGV Usage
by andyford (Curate) on Aug 30, 2007 at 15:24 UTC
Re: ARGV Usage
by jethro (Monsignor) on Aug 31, 2007 at 11:55 UTC
    Derby is right: Your perl code is correct. Check the unix script which should deliver the two values but probably does not.