I want to call a Perl subroutine on a remote host. How can it be done?
What I am trying to do is (which is not working):
my $sshCmd = "ssh";
my var1="ABC";
&sshToUpdateSim;
sub simUpdate
{
$var1="32";
print "inside sub, $var1 is var1\n";
}
sub sshToUpdateSim
{
system (" $sshCmd machinewin10 \"simUpdate() \""); ### Causing Issue (sh: simUpdate : command not found)
}
print "$var1 is var1 now";
Here, calling subroutine "simUpdate" on a remote host "machinewin10" is the requirement.
Help on it will be highly appreciated.
Thank You in Advance!
CodePudding user response:
This seems like an XY problem. What you're trying to do doesn't make much sense. We can probably suggest a better approach, but we would need a lot more context about the problem.
You are passing this string to system()
:
ssh machinewin10 "&simUpdate "
This uses ssh
to connect to 'machinewin10' and runs the command '&simUpdate'. The '&' has a special meaning to the remote machine's shell (it runs the preceding command as a background process - but there's no preceding command) and the error message tells you that there's no command simUpdate
on that machine - which should come as no surprise.
I can think of two things you might be wanting to do here.
You might want simUpdate()
to return a string that contains the command that you want to run on the remote machine. In which case you can't call the subroutine from inside a quoted string. You'd need something like this:
sub simUpdate {
return 'some_command';
}
sub sshToUpdateSim {
system ("$sshCmd machinewin10" . simUpdate());
}
Alternatively, you might actually want to run the subroutine on the remote machine. That's not going to work without rather a lot of work. You can't just run a subroutine from the command line. You will need to install a program that includes your subroutine onto the remote machine and then from your ssh
call you would run that program, passing it arguments that make it run your required subroutine. I don't have time to give a full solution for this option without knowing that it would be useful to you.
All in all, as I said at the start of this answer, you need to give us a lot more detail about what you're trying to do here.
Oh, and one more thing. Using ampersands on Perl subroutine calls is something that we haven't needed to do since Perl 5 was released in 1994. It still work (as you see) but it's generally a bad idea as it doesn't look like a subroutine call and can have strange side effects. See Subroutines and Ampersands for more details.
CodePudding user response:
Four problems:
- ssh takes a shell command, not Perl code.
- The code isn't anywhere on the machine, so it can't possibly execute the desired code.
- You can't execute subroutines from the command line, just programs.
- Changing a variable in another process, especially one on a different machine, won't have any effect on a variable in a different process.
use String::ShellQuote qw( shell_quote );
my $perl_code = <<'__EOS__';
my $var = "32";
print $var;
__EOS__
my $remote_cmd = shell_quote( "perl", "-e", $perl_code );
my $local_cmd = shell_quote( "ssh", "machinewin10", $remote_cmd );
my $var = `$local_cmd`;
This assumes the remote machine uses sh
or similar. With the name of the machine being machinewin10
, that's not a given. Adjust the remote command as necessary if that's not the case. Win32::ShellQuote might be useful.
Similarly, this assumes the local machine is unixy, where system
and readpipe
(backticks) use sh
. Adjust the local command as necessary if that's not the case.