我想SSH到服务器并执行一个简单的命令,如“id”,并获取它的输出并将其存储到我的主服务器上的文件中。我没有安装Net::SSH的权限,这将使我的任务变得非常简单。请为我提供一个解决方案。我尝试使用 back-ticks ,但我无法将输出存储在运行脚本的机器上。
答案 0 :(得分:14)
使用SSH远程运行命令的最佳方法是
$ ssh user@host "command" > output.file
您可以在bash或perl中使用它。但是,如果要使用perl,可以按照brian在其评论中的建议或在“How do I keep my own module/library directory?”的Perl FAQ中安装perl模块在本地目录路径中。我建议使用Net :: SSH :: Perl而不是使用Net :: SSH。
#!/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;
答案 1 :(得分:8)
您始终可以在本地安装模块,这是您应该考虑的方法;但是,你应该能够逃脱
#!/usr/bin/perl
use strict;
use warnings;
my $id = qx/ssh remotehost id 2>&1/;
chomp $id;
print "id is [$id]\n"
答案 2 :(得分:2)
或者,假设存在主机密钥并且您想要使用命令ouput ...
执行某些操作open(SSH,"/usr/bin/ssh you\@server ps aux |") or die "$!\n";
while (<SSH>) {
# do stuff with $_
}
close SSH;
答案 3 :(得分:1)
如果您正在使用反引号,请尝试以下操作:
my @output = `ssh root@1.1.1.1 "which perl"`;
print "output: @output";
这仅在您拥有上述命令不会提示输入密码的公钥时才有用。
答案 4 :(得分:1)
我有一个类似的问题,经过多次搜索,我找到了一个简单的选择。我使用qx()
并像往常一样运行ssh命令。我不得不捕获stderr和stdout。
以下是我使用的示例:
my $output = qx(ssh root\@$curIP python -V 2>&1);
它运行python -V
命令,将版本信息输出到stderr
。在此示例中,我的IP地址存储在$curIP
变量中。最后,2>&1
有助于捕获stdout和stderr。我没有指定密码,因为我有密钥交换设置。希望这会有所帮助。
答案 5 :(得分:0)
如果你有ssh主机密钥设置,你可以简单地运行ssh system命令,然后指定在此之后在机器上运行的命令。例如:
`ssh user@remoteserver.domain.com id`
您应该能够选择/存储该输出。
答案 6 :(得分:0)
假设您在像我这样的环境中无法添加其他模块且无法创建标识文件,那么您可以使用此脚本作为起点。
如果您可以设置ssh密钥,那么只需使用已发布的反引号命令,尽管您可能需要-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();
答案 7 :(得分:0)
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
}
}
答案 8 :(得分:0)
我知道这是一个非常老的线程,但是由于我遇到了同样的问题,我找到了另一个有用的解决方案,以防有人使用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来实现这一目标。
希望这有助于在不进行硬编码的情况下找到解决方案。