如果在Perl中与主机的连接失败,请重试SSH到主机
我有一个脚本,它对服务器执行SSH并执行一些命令(在这个脚本中,为了演示,我正在运行带有Hello消息的perlprint语句) 这是我的剧本:如果在Perl中与主机的连接失败,请重试SSH到主机,perl,ssh,Perl,Ssh,我有一个脚本,它对服务器执行SSH并执行一些命令(在这个脚本中,为了演示,我正在运行带有Hello消息的perlprint语句) 这是我的剧本: #!/usr/bin/perl use strict; use warnings; use Net::OpenSSH; $Net::OpenSSH::debug = ~0; BEGIN { open my $out, '>', '/tmp/debug.txt' or warn $!; $Net::OpenSSH::debug_f
#!/usr/bin/perl
use strict; use warnings;
use Net::OpenSSH;
$Net::OpenSSH::debug = ~0;
BEGIN {
open my $out, '>', '/tmp/debug.txt' or warn $!;
$Net::OpenSSH::debug_fh = $out;
$Net::OpenSSH::debug = -1;
}
my @hosts = ("ipaddress1","ipaddress2");
my $ssh;
my $command = "perl -e 'print \"Hello..\"'";
foreach my $n (@hosts) {
#Here if connection to the host($n) fails, is it possible to retry again
$ssh = Connect($n, "user", "passwd");
$ssh->capture($command);
print "Done execution in Host: $n\n";
}
undef $ssh;
print "**End**\n";
sub Connect {
my ( $host, $user, $passwd ) = @_;
my $ssh = Net::OpenSSH->new($host, user=>$user, password=>$passwd);
$ssh->error and die "Couldn't establish SSH connection: " . $ssh->error;
return $ssh;
}
每当我执行此脚本时,有时它会成功打印以下消息:
Done execution in Host: ipaddress1
Done execution in Host: ipaddress2
**End**
但有时无法对主机执行ssh操作(无论是ipaddress1
还是ipaddress2
),并给出以下消息:
Couldn't establish SSH connection: unable to establish master SSH connection: master process exited unexpectedly at script.pl ....
它在Connect
子例程中死亡(因为我无法跟踪,打开了问题)
那么,如果我无法连接(ssh)到主机,有没有办法在一段时间后重试(对于
n
number次),而不是打印错误消息并使脚本死掉?OpenSSH为错误提供了一个很好的接口。首先,我要看一下上面的例子。试试下面的方法
foreach my $n (@hosts) {
#Here if connection to the host($n) fails, is it possible to retry again
$ssh = Connect($n, "user", "passwd", 3);
$ssh->capture($command);
print "Done execution in Host: $n\n";
}
undef $ssh;
print "**End**\n";
sub Connect {
my ( $host, $user, $passwd , $retry_limit ) = @_;
my $timeout = 10;
my $con;
while ( $retry_limit-- > 0 )
{
$con = Net::OpenSSH->new($host,
user=>$user,
password=>$passwd,
timeout=> $timeout,
);
last unless $con->error();
}
die "unable to connect ".$con->error() if retry_limit <0;
return $con;
}
foreach my$n(@hosts){
#如果与主机($n)的连接失败,是否可以重试
$ssh=Connect($n,“用户”,“密码”,3);
$ssh->capture($command);
打印“在主机中完成执行:$n\n”;
}
未定义$ssh;
打印“**结束**\n”;
子连接{
我的($host、$user、$passwd、$retry\u limit)=@;
我的$timeout=10;
我的$con;
while($retry\u limit-->0)
{
$con=Net::OpenSSH->new($host,
用户=>$user,
密码=>$passwd,
超时=>$timeout,
);
最后,除非$con->error();
}
die“无法连接”。$con->error()如果重试\u limitOpenSSH为错误提供了一个很好的接口
foreach my $n (@hosts) {
#Here if connection to the host($n) fails, is it possible to retry again
$ssh = Connect($n, "user", "passwd", 3);
$ssh->capture($command);
print "Done execution in Host: $n\n";
}
undef $ssh;
print "**End**\n";
sub Connect {
my ( $host, $user, $passwd , $retry_limit ) = @_;
my $timeout = 10;
my $con;
while ( $retry_limit-- > 0 )
{
$con = Net::OpenSSH->new($host,
user=>$user,
password=>$passwd,
timeout=> $timeout,
);
last unless $con->error();
}
die "unable to connect ".$con->error() if retry_limit <0;
return $con;
}
foreach my$n(@hosts){
#如果与主机($n)的连接失败,是否可以重试
$ssh=Connect($n,“用户”,“密码”,3);
$ssh->capture($command);
打印“在主机中完成执行:$n\n”;
}
未定义$ssh;
打印“**结束**\n”;
子连接{
我的($host、$user、$passwd、$retry\u limit)=@;
我的$timeout=10;
我的$con;
while($retry\u limit-->0)
{
$con=Net::OpenSSH->new($host,
用户=>$user,
密码=>$passwd,
超时=>$timeout,
);
最后,除非$con->error();
}
die“无法连接”。$con->error()如果重试(由于您编写的代码将导致它死亡
),为什么不通过将connect
调用包装在eval{…connect(…);capture();};如果($@){异常发生}中来捕获它作为异常呢
?@tedlynmo好的。在这种情况下,eval
的重试限制是多少。如果我传递了不正确的user
或passwd
,结果会是什么?它将尝试连接多少次。eval{…};if($@{…}
只是在perl中进行异常处理的一种方法,比如try>{…}catch(…){…}
在其他语言中。捕获异常时的操作取决于您自己。您可以减少一个计数器,并在几次尝试后停止,就像下面得到的答案一样(这样做没有异常处理)。既然您已经编写了将导致它死亡的代码,为什么不通过将Connect
调用包装在eval{…Connect(…);capture();};if($@{异常发生}中来捕获它作为异常呢
?@tedlynmo好的。在这种情况下,eval
的重试限制是多少。如果我传递了不正确的user
或passwd
,结果会是什么?它将尝试连接多少次。eval{…};if($@{…}
只是在perl中进行异常处理的一种方法,比如try>{…}catch(…){…}
在其他语言中。捕获异常时,您将如何处理取决于您自己。您可以减少计数器,然后在几次尝试后停止,就像下面得到的答案中所示(这样做没有异常处理)。在我看来,perl-e'my$rt=3;而($rtYes,更改它也会起作用。如果保留后增量运算符,失败时将是-1
。在循环中使用与之后相同的值是i.m.o。这意味着您可以在两个位置使用到布尔值的隐式转换,并在(-$retry\u limit){…}死亡时执行,除非($retry_limit);
但是可以肯定,>0
和<0
是有效的。同意,可能是最清楚的,die“无法连接”。$con->error()如果$con->error()是的,这可能是一个更好的选择-或者如果连接成功,从循环内部返回。返回$con,除非$con->error;
-循环结束后不需要检查任何东西-只要死亡
。对我来说,这看起来没问题perl-e'my$rt=3;而($rtYes,更改它也会起作用。如果保留后增量运算符,失败时将是-1
。在循环中使用与之后相同的值是i.m.o。这意味着您可以在两个位置使用到布尔值的隐式转换,并在(-$retry\u limit){…}死亡时执行,除非($retry_limit);
但是可以肯定,>0
和<0
是有效的。同意,可能是最清楚的,die“无法连接”。$con->error()如果$con->error()是的,这可能是一个更好的选择-或者如果连接成功,就从循环内部返回。返回$con,除非$con->error;
-无需在循环后检查任何内容-只要死亡
。