我有这段代码:
$script = "console.log(\"It works!\");";
$output = qx/ssh user@123.123.123.123 $script | interpreter/;
它应该通过解释器运行$script
并将其写入$output
。问题是它不起作用。如何正确地转义字符?
答案 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脚本中查看system
或qx//
次调用是一个麻烦的迹象。一般来说,当我不编写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');