2012-03-09 14 views
3

私はこのコードを持っている:Perlでsshのバッククォートの文字を正しくエスケープするには?

$script = "console.log(\"It works!\");"; 
$output = qx/ssh [email protected] $script | interpreter/; 

通訳を通じて$scriptを実行し、$outputにそれを書くことになっています。問題は、それが動作しないということです。文字を正しくエスケープするにはどうしたらいいですか?

+1

リモートホストまたはローカル1の「通訳」を実行するために欠けていますか? –

+1

私はすでに2つのVMの間でssh経由でnopassword接続を設定しました。私はリモートホスト上にあるインタプリタ(この場合はノード)を呼び出しています。 – AlfredoVR

+2

あなたのコマンドはあまり意味がありません。今は 'sshを実行しています... | 'ssh'の出力をローカルホストの' interpreter'にパイプしています。リモートホスト上で 'interpreter'を実行する場合は、' ssh'の引数の中に入れなければなりません。 'qx/ssh [email protected] 'のようなもの$ script |通訳者。 – ruakh

答えて

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

注意私の文字列にはカッコがあります。これらのかっこがバランスしている限り、これは問題ありません。この1は機能しません。

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

それはいいですし、すべての人々は本当に物事をエスケープすることを心配することなくバッククォートで何かを実行する方法を教える必要があります。 – tchrist

4

を考えますあなたがsshだけで何をしようとしているかについて。これらの両方は、同じ出力を生成するが、異なる動作:最初に

ssh [email protected] 'echo "puts 2+2" | ruby' 
echo "puts 2+2" | ssh [email protected] ruby 

を、リモートシェルは、パイプラインを実行しています。 (もしあなたが一重引用符を持っていなければ、何が起こるのでしょうか?)2番目の方法では、ローカルシェルを通して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 [email protected] 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) 

systemqx//見ますperlスクリプトの呼び出しは問題の兆候です。一般的に、私はシェルを書いていないときに、シェル構文やシェル引用について考える必要はありません。それは私が解決しようとしている問題や、それを解決しているツールとは何の関係もありません。 (セキュリティの意味を無視しています)

標準入力ではなく、他のプログラムの出力を実行してキャプチャしたい場合は、常にIPC::System::Simpleです。

+1

さて、私は小さな子供としてCPANのSSHモジュールのいくつかに傷つきました。 –

+0

私はあまりにも、私はそれらを正しくインストールするために20回試みましたが、彼らは私を好きではありません。 – AlfredoVR

関連する問題