web-dev-qa-db-ja.com

Perlスクリプト内でsshするにはどうすればよいですか?

サーバーにSSHで接続し、「id」のような単純なコマンドを実行して、その出力を取得し、プライマリサーバーのファイルに保存します。インストールする権限がありません Net :: SSH これにより、作業が非常に簡単になります。この解決策を教えてください。 back-ticksを使用してみましたが、スクリプトを実行するマシンに出力を保存できません。

10
Salman

SSHを使用してリモートでコマンドを実行する最良の方法は、

$ ssh user@Host "command" > output.file

これはbashまたはPerlのどちらでも使用できます。ただし、Perlを使用する場合は、brianのコメントまたはPerl FAQ at " How do I keep my my自身のモジュール/ライブラリディレクトリ? "。Net :: SSHを使用する代わりに、以下の例ではNet :: SSH :: Perlを使用することをお勧めします。

#!/usr/bin/Perl -w
use strict;
use lib qw("/path/to/module/");

use Net::SSH::Perl;

my $hostname = "hostname";
my $username = "username";
my $password = "password";

my $cmd = shift;

my $ssh = Net::SSH::Perl->new("$hostname", debug=>0);
$ssh->login("$username","$password");
my ($stdout,$stderr,$exit) = $ssh->cmd("$cmd");
print $stdout;
14
Space

モジュールはいつでもローカルにインストールできます。これが調査すべき方法です。しかし、あなたは逃げることができるはずです

#!/usr/bin/Perl

use strict;
use warnings;

my $id = qx/ssh remotehost id 2>&1/;

chomp $id;

print "id is [$id]\n"
8
Chas. Owens

または、ホストキーが存在し、コマンドouput ...

open(SSH,"/usr/bin/ssh you\@server ps aux |") or die "$!\n";
while (<SSH>) { 
   # do stuff with $_ 
}
close SSH;
2
James

私も同様の問題を抱えていましたが、よく調べたところ、簡単なオプションが見つかりました。私はqx()を使用して、通常どおりにsshコマンドを実行しました。問題は、標準エラーと標準出力の両方をキャプチャする必要があることです。

以下は私が使用したものの例です:

my $output = qx(ssh root\@$curIP python -V 2>&1);

python -Vコマンド。バージョン情報をstderrに出力します。この例では、私のIPアドレスは$curIP変数。最後に、2>&1 stdoutとstderrの両方をキャプチャするのに役立ちます。鍵交換の設定があるため、パスワードを指定しませんでした。お役に立てれば。

1
James Oravec

バックティックを使用している場合は、これを試してください。

my @output = `ssh [email protected] "which Perl"`;

print "output: @output";

これは、上記のコマンドでパスワードの入力を求められない公開鍵がある場合にのみ役立ちます。

1
Ricky Levi

私のように、モジュールを追加できず、Identityファイルを作成できない環境にいるとすると、このスクリプトを開始点として使用できます。

Sshキーを設定できる場合は、すでに投稿されているbackticksコマンドを使用しますが、-iオプションが必要になる場合があります。

#!/usr/bin/Perl
use warnings;
use strict;
use Expect;
use Data::Dumper;

my $user = 'user';
my $pw = 'password';
my $Host = 'Host';
my $cmd = 'id';

my $exp = new Expect;
$exp->log_file("SSHLOGFILE.txt");
$exp->log_stdout(0);
$exp->raw_pty(1);


my $cli = "/usr/bin/ssh $user\@$Host -o StrictHostKeyChecking=no -q $cmd";

$exp->spawn($cli) or die "Cannot spawn $cli: $!\n";

$exp->expect(5,
 [ qr /ssword:*/ => sub { my $exph = shift;
                          $exph->send("$pw\n");
                          exp_continue; }] );

my $read = $exp->exp_before();
chomp $read;
print Dumper($read);

$exp->soft_close();
0
John Mikkola

これは非常に古いスレッドであることはわかっていますが、同じ問題が発生したため、誰かがLinuxを使用している場合に役立つ別の解決策を見つけました。

#!/usr/bin/Perl
use strict;
use warnings;
use Data::Dumper;

my $Host = $ARGV[0];
my $port = $ARGV[1];
my $cmd = $ARGV[2];

my @output = readpipe( "ssh -p ".
               $port." ".
               $Host." ".
               $cmd."" );

chomp @output;

print Dumper \@output;

__END__

Perl sample.pl 127.0.0.1 22 "which Perl"
Ubuntu 16.04.1 LTS
$VAR1 = [
          '/usr/bin/Perl'
        ];

これは、ssh-keysが構成されていることを前提としているため、ユーザー入力は必要ありません。ハードコードされた値が欲しくなかったので、これは私にとって最良の方法でした。私は readpipe を使用してそれを達成しています。

これがハードコーディングではない場合の解決策となることを願っています。

0
Thanos
use warnings;
use strict;
use NET::SSH2;

sub is_sshalive;

my $Host = "ip"; # use the ip Host to connect
my $user = "UNAME"; # your account
my $pass = "PASSWD"; # your password
my $cmd;
my $ssh2 = Net::SSH2->new();
$ssh2->debug(1);
if ($ssh2->connect($Host)) {
    #if ($ssh2->auth_password($user,$pass)) {
    if ($ssh2->auth_keyboard($user,$pass)) {
        print "\n Executing command...\n";
        $cmd = "ls";
        print " ==> Running $cmd\n";
        if(is_sshalive($ssh2) == 1) {
                print "\nSSH connection died";
                exit 1;
        } else {
            run_testsuite($cmd, $ssh2);
        }
    } else {
        warn "ssh auth failed.\n";
        exit 1;
    }
} else {
    warn "Unable to connect Host $Host \n";
    exit 1;
}
print "test passed done 0\n";


sub run_testsuite {
    my $cmd = $_[0];
    my $ssh2 = $_[1];

    my $chan2 = $ssh2->channel();
    $chan2->Shell();
    print $chan2 "$cmd \n";
    print "LINE : $_" while <$chan2>;
    $chan2->close;
    return 0;
}

sub is_sshalive {
    my $ssh2 = $_[0];
    if ($ssh2->poll(1000) == 0) {
        return 0; # passed
    } else {
        return 1; #failed
    }
}
0
bicepjai

Sshホストキーを設定している場合は、sshシステムコマンドを実行し、その後マシンで実行するコマンドを指定するだけです。例えば:

`ssh [email protected] id`

その出力をチョップ/保存できるはずです。

0
malonso