【问题标题】:How to properly escape characters for backquotes for ssh in Perl?如何在 Perl 中正确转义 ssh 的反引号字符?
【发布时间】:2012-03-10 00:32:51
【问题描述】:

我有这个代码:

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

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

【问题讨论】:

  • 你想在远程主机还是本地主机上运行“解释器”?
  • 我已经在两个虚拟机之间通过 ssh 建立了无密码连接。我正在调用远程主机上的解释器,在本例中为节点。
  • 您的命令不太合理。现在您正在运行ssh ... | interpreter,也就是说,您正在将ssh 的输出传送到本地主机的interpreter。如果你想在远程主机上运行interpreter,那么你需要把它放在ssh的参数里面;类似qx/ssh user@123.123.123.123 '$script | interpreter'
  • 实际上,在所有情况下,您都无法安全地处理反引号。您必须使用带有多个单独参数的管道打开。

标签: perl bash ssh


【解决方案1】:

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

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

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

我更喜欢通过标准输入将文本输入管道,而不是执行复杂的代码转义以在通过 sh 时正确输出。它只是更简单。

使用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 总是有的。

【讨论】:

  • 顺便说一句,我想指出,我小时候被 CPAN 的几个 SSH 模块伤痕累累。
  • 我也是,我尝试了二十次才能正确安装它们,但它们不喜欢我。
【解决方案2】:

由于您使用的是 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);

【讨论】:

  • 这很好,真的应该教人们如何在反引号中运行某些东西而不必担心转义。
【解决方案3】:

使用Net::OpenSSH:

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

【讨论】:

    猜你喜欢
    • 2015-08-26
    • 2015-07-14
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 2018-01-06
    相关资源
    最近更新 更多