如何在Perl中为ssh的反引号正确转义字符?

时间:2012-03-09 03:36:35

标签: perl bash ssh

我有这段代码:

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

它应该通过解释器运行$script并将其写入$output。问题是它不起作用。如何正确地转义字符?

3 个答案:

答案 0 :(得分:4)

想想你正在尝试用ssh做什么。这两个产生相同的输出,但工作方式不同:

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

在第一个中,远程shell正在执行管道。 (如果你没有那些单引号,会发生什么?)在第二个,它通过本地shell传送到ssh命令并启动解释器。

我不喜欢在通过sh填充时执行错误的代码转义,而是通过stdin来管理文本。它更简单。

使用IPC::Run完成所有繁重任务:

#!/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是一个简单的中缀计算器程序,我躺在那里)

这是我得到的输出,运行:

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

在perl脚本中查看systemqx//次调用是一个麻烦的迹象。一般来说,当我不编写shell时,我不喜欢考虑shell语法或shell引用;它与我试图解决的问题无关,也与我正在解决的问题无关。 (这忽略了任何安全隐患。)

哦,如果您不需要使用标准输入,但仍想执行并捕获其他程序的输出,则总是IPC::System::Simple

答案 1 :(得分:3)

由于你使用的是Perl,你应该在Perl中进行,而不是调用外部命令。

您是否尝试过Perl模块Net::SSH::Perl

在设置$script的值时,我还会使用qq而不是引号。使用qq删除整个如何引用引号混乱。 qq之后是字符串分隔符后的任何字符。所有这些都是有效的:

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*;

特殊匹配报价运算符为()[],以及{}

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

请注意,我可以使用括号作为我的字符串分隔符,即使我的字符串中有括号。只要这些括号是平衡的,这是可以的。这个不行:

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

但是,我可以切换到方括号或花括号:

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

这是你的程序的Perl版本:

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);

答案 2 :(得分:0)

使用Net::OpenSSH

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