How do I properly escape characters for backquotes for ssh in Perl?

I have this code:

$script = "console.log(\"It works!\");";
$output = qx/ssh user@123.123.123.123 $script | interpreter/;

      

It should run $script

through the interpreter and write it to $output

. The problem is, it doesn't work. How can I escape characters correctly?

+3


source to share


3 answers


Think about what you are trying to do with ssh alone. They both produce the same output, but work in different ways:

ssh user@host 'echo "puts 2+2" | ruby'
echo "puts 2+2" | ssh user@host ruby

      

In the first, the remote shell executes the pipeline. (If you don't have those single quotes, what happens?) In the second case, it was piped through your local shell to the ssh command and the interpreter was started.

Instead of doing folded code escapes to exit properly when overflowed via sh, I prefer to stream the text via stdin. It's just easier.

Using IPC :: Run , 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 lay in)

Here's the output I get works that:

out: 4
40
err: (SSH banners and pointless error messages)

      


Observing system

or qx//

calling in a perl script is a sign of a problem. In general, I don't like to think about shell syntax or shell quoting when I am not writing a shell; it has nothing to do with the problem I'm trying to solve, nor the tool I'm solving it with. (And this ignores any security implications.)

Oh, and if you don't have to guess with standard input, but still want to execute and capture output from other programs, always IPC :: System :: Simple .

+4


source


Since you are using Perl, you must do this in Perl and not call an external command.

Have you tried the Perl Net :: SSH :: Perl module ?

I also used qq instead of quotes when setting the value $script

. Usage qq

removes everything as I quote the mess of quotes. What happens after the character qq

is your line separator. They are all valid:

my $string = qq/This is a "string" with a quote/;
my $string = qq|This is a "string" with a quote|;
my $string = qq*This is a "string" with a quote*;

      

Special citation operators match (

and )

, [

and ]

, and {

and }

:

my $string = qq(This (is (a "string" with) a) quote);

      



Note that I can use parentheses as line separators even though my line has parentheses in it. It's okay if these brackets are balanced. It won't work:

my $string qq(This is an "unbalanced" parentheses ) that breaks this statement);

      

But then I can switch to square brackets or curly braces:

my $string qq[This is an "unbalanced" parentheses ) but still works.];

      

Here's the Perl version of your program:

use strict;     #Always use!
use warnings;   #Always use!
use Net::SSH::Perl;

#
# Use Constants to set things that are ...well... constant
#
use constant {
   HOST => "123.123.123.123",
   USER => "user",
};

my $script = qq[console.log("It works!");];
my $connection = Net::SSH::Perl->new(HOST);
$connection->login(USER);
my ($output, $stderr, $exit_code) = $connection->cmd($script);

      

+3


source


use Net :: OpenSSH :

my $ssh = Net::OpenSSH->new('user@123.123.123.123');
my $output = $ssh->capture({stdin_data => 'console.log("It works!");'},
                           'interpreter');

      

0


source







All Articles