サーバーにSSHで接続し、「id」のような単純なコマンドを実行して、その出力を取得し、プライマリサーバーのファイルに保存します。インストールする権限がありません Net :: SSH これにより、作業が非常に簡単になります。この解決策を教えてください。 back-ticksを使用してみましたが、スクリプトを実行するマシンに出力を保存できません。
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;
モジュールはいつでもローカルにインストールできます。これが調査すべき方法です。しかし、あなたは逃げることができるはずです
#!/usr/bin/Perl
use strict;
use warnings;
my $id = qx/ssh remotehost id 2>&1/;
chomp $id;
print "id is [$id]\n"
または、ホストキーが存在し、コマンドouput ...
open(SSH,"/usr/bin/ssh you\@server ps aux |") or die "$!\n";
while (<SSH>) {
# do stuff with $_
}
close SSH;
私も同様の問題を抱えていましたが、よく調べたところ、簡単なオプションが見つかりました。私はqx()
を使用して、通常どおりにsshコマンドを実行しました。問題は、標準エラーと標準出力の両方をキャプチャする必要があることです。
以下は私が使用したものの例です:
my $output = qx(ssh root\@$curIP python -V 2>&1);
python -V
コマンド。バージョン情報をstderr
に出力します。この例では、私のIPアドレスは$curIP
変数。最後に、2>&1
stdoutとstderrの両方をキャプチャするのに役立ちます。鍵交換の設定があるため、パスワードを指定しませんでした。お役に立てれば。
バックティックを使用している場合は、これを試してください。
my @output = `ssh [email protected] "which Perl"`;
print "output: @output";
これは、上記のコマンドでパスワードの入力を求められない公開鍵がある場合にのみ役立ちます。
私のように、モジュールを追加できず、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();
これは非常に古いスレッドであることはわかっていますが、同じ問題が発生したため、誰かが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 を使用してそれを達成しています。
これがハードコーディングではない場合の解決策となることを願っています。
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
}
}
Sshホストキーを設定している場合は、sshシステムコマンドを実行し、その後マシンで実行するコマンドを指定するだけです。例えば:
`ssh [email protected] id`
その出力をチョップ/保存できるはずです。