I have this code:
$script = "console.log(\"It works!\");";
$output = qx/ssh [email protected] $script | interpreter/;
It's supposed to run $script through interpreter and write it into $output. The problem is that it doesn't work. How do I escape the characters correctly?
Think about what you're trying to do just with ssh. Both of these produce the same output, but work differently:
ssh user@host 'echo "puts 2+2" | ruby'
echo "puts 2+2" | ssh user@host ruby
In the first, the remote shell is executing the pipeline. (If you don't have those single quotes, what happens?) In the second, it's piped through your local shell to the ssh command and the interpreter launched.
Rather than perform convoluted escapes of code to come out correctly when crammed through sh, I prefer to pipe the text in through stdin. It's just simpler.
Using IPC::Run to do all the heavy lifting:
#!/usr/bin/env perl
use strict;
use warnings;
use IPC::Run qw(run);
my $in = <<FFFF;
2 + 2
8 * (2 + 3)
FFFF
my $cmd = [qw(ssh user@host perl calc.pl)];
run $cmd, \$in, \my $out, \my $err or die "ssh: $?";
print "out: $out";
print "err: $err";
(calc.pl is a simple infix calculator program that I had lying around)
Here's the output I get, running that:
out: 4
40
err: (SSH banners and pointless error messages)
Seeing system or qx// calls in a perl script is a sign of trouble. In general, I don't like having to think about shell syntax or shell quoting when I'm not writing shell; it has nothing to do with the problem I'm trying to solve, nor the tool I'm solving it with. (And that's ignoring any security implications.)
Oh, and if you don't have to muck with standard input but still want to execute and capture output from other programs, there's always IPC::System::Simple.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With