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

I know absolutely nothing about Perl (I don't know much about computers in general). However, I was just handed a .pl file and told I could modify it to make it work for me. I'm sure this answer is easy, but I'm not even sure of the right lingo to find the answer. The file starts with:

print "Enter base name of input files\n"; chomp ($basename = <STDIN>);

I understand that this just prompts me for a variable name. If I replace  <STDIN> with  'filename', it uses the file appropriately. My question is, can I start this .pl file and pass this variable at the same time without having to go in and edit the .pl file each time? I'd expect something like:

 ./file.pl $basename='filename'

It would be even easier if I could just execute this with:

 ./file.pl filename

I'm trying to submit a bunch of files to be run batch on a parallel cluster, and I'm sick of having to go in and change every file name in the .pl file. Any words of wisdom? Again, take it easy on me. I've searched around and can't find the exact answer.

Replies are listed 'Best First'.
Re: adding a variable definition to execution
by Your Mother (Archbishop) on May 21, 2009 at 22:25 UTC
    use strict; # DON'T FORGET TO use warnings; # DO THESE! # the shift is implicitly acting on @ARGV. my $base_name = shift; unless ( $base_name ) { print "Enter base name of input files: "; chomp ( $base_name = <STDIN> ); } # die() or retry a read from <STDIN> if there # is no $base_name at this point. # Then check to see if $base_name has a valid value. # Continue on. Happy Perl!
Re: adding a variable definition to execution
by akho (Hermit) on May 21, 2009 at 22:17 UTC
    $basename = shift should work for your needs. (execute with ./file.pl filename)
Re: adding a variable definition to execution
by Perlbotics (Archbishop) on May 21, 2009 at 22:25 UTC

    As a quick-start, you could wrap the interactive part like so:

    ... if (@ARGV) { # test if there is at least one argument $basename = $ARGV[0]; # set basename to first argument } else { # otherwise be interactive print "Enter base name of input files\n"; chomp ($basename = <STDIN>); } ...
    Now, you can provide the filename as first argument or fall back into interactive mode. See e.g. Getopt::Long for another approach. Be careful with $var = shift; since it behaves different when called from inside or outside of a subroutine.

Re: adding a variable definition to execution
by lostjimmy (Chaplain) on May 21, 2009 at 22:29 UTC

    If I replace <STDIN> with 'filename' , it uses the file appropriately
    Not quite. You actually have to replace <STDIN> with a file handle, not a filename.

    If you get the filename from the command line like you want to, it ends up in @ARGV. The first argument on the command line is in $ARGV[0], the second in $ARGV[1], and so on. Using a simple shift like akho has suggested simply grabs (and removes) the first element off of @ARGV. You could also do this: $basename = $ARGV[0]

    If you gave us some more information, we could offer much more advice. I have a feeling that these answers will only lead to more questions, so bring it on.

      You actually have to replace <STDIN> with a file handle, not a filename.

      I believe the original poster replaced the input with a hard-coded value; that is, wrote $basename = 'filename'. A filehandle would be an error, probably.

Re: adding a variable definition to execution
by bichonfrise74 (Vicar) on May 21, 2009 at 22:41 UTC
    Just use something like...
    my $basename = $ARGV[0] if defined(@ARGV);
Re: adding a variable definition to execution
by Your Mother (Archbishop) on May 22, 2009 at 04:59 UTC

    And because it hasn't been mentioned, look at Getopt::Long. It's a little complex at first but it's great for passing full *nix style arguments to scripts. Search around here for it if you're interested. There are plenty of other goodies for making scripts easy for the hacker and the user; e.g., Pod::Usage comes to mind.