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

Dear monks, I have a shell script with a perl oneliner in it, and want to pass a shell variable to this oneliner.
The idea is this:
#!/bin/bash file=$1 var=$2 cat $1 | perl -e 'perlcodeinhere' >output
The question is how to get the $var variable into the perl code since I apparently can not get in is as regular argument while using the -e parameter.

Rgds, Ole C.

Update:
Thanks for the input, several nice ways of doing it.
I will also be sure to utilize the perl pie construct in the future, that is most certainly usefull for quite a few of my daily tasks.

Another Update:
As Bart points out it is possible to have the variable as a regular argument. What kept me from realising that was that I was using a while(<>) loop inside my code, my entire oneliner was like this:
cat $i | perl -e 'while(<>){$_=~ s/$ARGV[0]//g;print;}' $var >$i.new
and that did not work. I guess that is because the while(<>) expects to find files to work on in the @ARGV list. When I changed it to
cat $i | perl -e 'while(<STDIN>){$_=~ s/$ARGV[0]//g;print;}' $var >$i. +new
it worked the way I expected.

Replies are listed 'Best First'.
Re: arguments to perl -e
by borisz (Canon) on Apr 07, 2006 at 16:57 UTC
    Perhaps this way:
    export MYVAR='xyz' perl -e 'print $ENV{MYVAR}'
    Boris
Re: arguments to perl -e
by explorer (Chaplain) on Apr 07, 2006 at 17:02 UTC
    #!/bin/bash file=$1 var=$2 cat $file | perl -e 'BEGIN { $var = $ARGV[0] } print <STDIN>' $var > o +utput
      Other solution. Insert $var variable before the file and send the stream. The Perl script will read it at BEGIN step:
      #!/bin/bash file="timer" var="Two" (echo $var; cat $file) | perl -e 'BEGIN { $var=<> } print <>; END { p +rint $var }' > output

      Ok... Is UGLY, I know it... but I have impatience!

Re: arguments to perl -e
by kwaping (Priest) on Apr 07, 2006 at 19:34 UTC
    Have you considered reworking your solution using perl pie instead of wrapping a one-liner in a shell script?

    ---
    It's all fine and dandy until someone has to look at the code.
Re: arguments to perl -e
by jcc (Sexton) on Apr 07, 2006 at 19:13 UTC
    I've been trying to come up to a solution for this using the -s flag to enable me to pass an additional custom flag with the variable as a parameter to the -e code. Why can't I use something like
    perl -e -s -foo=bar 'print $foo'
    UPDATE:
    Turns out I can... thanks all:
    #!/bin/ksh var=bar perl -se 'print $foo' -- -foo=${var}
      I had seen the "-s" option before, when reading perlrun, but had never tried using it till seeing your post. From what I can tell (on macosx 10.4.6, perl 5.8.6), it seems to work only if the script is stored in a file, and has a shebang line with this option flag -- and even then, it doesn't seem to work as advertised, unless the script is executable (runnable without passing it as an arg to "perl"):
      $ perl -s -foo=bar -e 'print $foo,$/ if $foo' Unrecognized switch: -foo=bar (-h will show valid options). # (and similarly with other arrangements of these args) $ cat junk.pl #!/usr/bin/perl -s print "$foo\n" if $foo; $ perl junk.pl $ perl junk.pl -foo 1 $ perl junk.pl -foo=bar 1 # (I thought that should have printed "bar", but # there must be some logical reason why it didn't.) $ chmod +x junk.pl $ junk.pl $ junk.pl -foo 1 $ junk.pl -foo=bar bar # at last!
      So -s is just not suitable for use with a one-liner script on the command line. Oh well. At least there are other ways of doing this sort of thing (as indicated by earlier replies).

      UPDATE: Turns out the one-liner command-line script approach actually does work if you do it like this:

      $ perl -se 'print "$foo\n" if $foo' -- -foo 1 $ perl -se 'print "$foo\n" if $foo' -- -foo=bar bar
      (thanks to blockhead for pointing this out to me.) There was something about the double-dash arg in the perlrun description of "-s", but it didn't seem to apply to this facet of perl's behavior.
      huh, I almost thought it is impossible to make `-s` work when perl is called with `-i`, `-p` and `-e` but it can! The only way it could work is like: perl -p -i -s -e 's/haha/$i/ge' -- -i=gaga "${FILES[@]}" Thanks for all suggestions that made me find out this.
Re: arguments to perl -e
by bart (Canon) on Apr 09, 2006 at 08:30 UTC
    The question is how to get the $var variable into the perl code since I apparently can not get in is as regular argument while using the -e parameter.
    Of course you can. There is no need for @ARGV to only contain a files list.
    perl -le 'print shift' foo
    If the variable contains spaces, you may have to quote it.

    You can even combine this with a file list passed as parameters:

    perl -e '$x = shift; while (<>) { print "$x: $_" }' $2 $1
    or even
    perl -nle 'BEGIN { $x = shift } print "$x: $_"' $2 $1