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

I'm trying to run the following command to ssh to a server and run my script and pass that script the values captured by this perl script, but when I run the script it does not pick up the actual variable values, it just simply prints out the actual words:

use warnings; use strict; my $arg0 = $ARGV[0]; my $arg1 = $ARGV[1]; my $arg2 = $ARGV[2]; my $arg3 = $ARGV[3]; my $arg4 = $ARGV[4]; my $arg5 = $ARGV[5]; my $arg6 = $ARGV[6]; my $arg7 = $ARGV[7]; system('D:\\SiteScope\\tools\\plink.exe -ssh user@server -pw Password +. ./scripts/myscript.sh $arg1 $arg2 $arg3');

I figure it's because perl interprets anything in between the single quotes as actual text and is not able to determine that the $arg1 $arg2 $arg3 are variables. How can I get this to work? I've tried everything I've read on this site. The command works as written and executes the remote shell script, it just doesn't pass the variable values to the script.

Replies are listed 'Best First'.
Re: Using system to run exe on Windows and pass it variables
by stevieb (Canon) on Sep 14, 2016 at 21:52 UTC

    Single quotes do not allow for interpolation of variables. Use double-quotes instead.

    Also, please edit your question and wrap your code within <code></code> tags per How do I post a question effectively?. As you can see, it's very hard to tell where your code is in your post, and it doesn't render correctly.

      OK, I updated my code and pasted my code back into the original post. This executes just fine, no errors. Just will not pass variable values. I tried double-quotes instead of the single quotes but this fails. Note that I declare all of the variables in the code, but I only need to pass specific ones to my remote script.
Re: Using system to run exe on Windows and pass it variables
by pryrt (Abbot) on Sep 14, 2016 at 21:25 UTC
Re: Using system to run exe on Windows and pass it variables
by kcott (Archbishop) on Sep 15, 2016 at 06:22 UTC

    G'day trmn8tr,

    Welcome to the Monastery.

    "use warnings; use strict; my $arg1 = $ARGV1; my $arg1 = $ARGV2; my $arg1 = $ARGV3; system('plink.exe -ssh me@myserver -pw password . ./scripts/myscript.sh $arg1 $arg2 $arg3');"

    Beyond the issue with code tags that stevieb pointed out (i.e. all three [n] parts are rendered as links — described in "What shortcuts can I use for linking to other information?"), you have an additional problem which is probably caused by typing your code in by hand. What you've ended up with is three declarations for $arg1. Had you tried to run this code, it would have failed to compile and aborted something like this:

    $ perl -E 'my $arg1 = $ARGV[1]; my $arg1 = $ARGV[2]; my $arg1 = $ARGV[ +3]; say $arg2; say $arg3' "my" variable $arg1 masks earlier declaration in same scope at -e line + 1. "my" variable $arg1 masks earlier declaration in same scope at -e line + 1. Global symbol "$arg2" requires explicit package name (did you forget t +o declare "my $arg2"?) at -e line 1. Global symbol "$arg3" requires explicit package name (did you forget t +o declare "my $arg3"?) at -e line 1. Execution of -e aborted due to compilation errors.

    [Note: I have $PERL5OPT set to '-Mstrict -Mwarnings -Mautodie' (see perlrun)]

    If you copy and paste your code, you'll avoid these sorts of typos; not to mention saving yourself a lot of unnecessary work.

    Array indices are zero-based: the first element of @ARGV is $ARGV[0]. Did you really intend to set $arg1 to the 2nd argument ($ARGV[1]), $arg2 to the 3rd argument and $arg3 to the 4th argument? If so, these variables are extremely poorly named and your code is highly error-prone!

    You might also consider using an array slice (e.g. @ARGV[0..2]). If you're unfamiliar with this construct, see "perlintro: Perl variable types".

    See the system function documentation. Note that this function takes a list: so use one. There is no benefit in attempting to construct a string in which some parts aren't interpolated (e.g. @myserver) and some parts are (e.g. $arg1). You probably could have removed all three declarations and assignments and just written:

    system qw{plink.exe -ssh me@myserver -pw password . ./scripts/myscript +.sh}, @ARGV[0..2];

    That's obviously untested; this isn't:

    $ perl -E 'system qw{ls -l}, @ARGV[0..2]' x y z -rw-r--r-- 1 ken staff 0 15 Sep 15:02 x -rw-r--r-- 1 ken staff 0 15 Sep 15:02 y -rw-r--r-- 1 ken staff 0 15 Sep 15:02 z

    — Ken

      Putting this into an array slice seems to have worked! Here is my new code I'm using to call out specific variables:
      use warnings; use strict; system qw{D:\\SiteScope\\tools\\plink.exe -ssh user@myserver -pw Passw +ord . ./scripts/myscript.sh}, @ARGV[1,6,7];
Re: Using system to run exe on Windows and pass it variables
by dasgar (Priest) on Sep 15, 2016 at 01:14 UTC

    A technique that I typically use when I need to run a system command (with system(), backticks, or Capture::Tiny) is to build up the command and store it in a variable. Then I can print out that variable to make sure that I have the command exactly the way that I need/want it to be. That helps me to catch issues with incorrect interpolation due to my mistakes.

    The side effect of this technique is that the executing the command becomes very simple - i.e. system($cmd);