我的perl代码不允许超过10个分叉。对于以下perl代码,每当我在读入脚本的机器列表中使用10台以上的机器时,perl脚本只会为10台机器分配10个进程,其余的则会因错误而死:
SSHProcessError ssh进程已终止。在serverLogin.pl 44 它死在$ ssh-> waitfor('主机的真实性',15)的那一行;。
PERL SCRIPT:
#!/usr/bin/perl -w
use Net::SSH::Expect;
use Term::ReadKey;
print "please enter filename:\n";
$filename = ReadLine;
chomp $filename;
print "please enter user ID:\n";
$userID = ReadLine;
chomp $userID;
print "please enter password:\n";
ReadMode 'noecho';
$passwordforuser = ReadLine 0;
chomp $passwordforuser;
ReadMode 'normal';
open READFILE,"<","$filename" or die "Could not open file listofmachines\n";
my @listofmachines = <READFILE>;
foreach $machine (@listofmachines)
{
my $pid=fork();
if ($pid){
push(@childprocs,$pid);
}
elsif ( $pid == 0 ) {
my $ssh = Net::SSH::Expect->new (
host => "$machine",
user => "$userID",
password=> "$passwordforuser",
timeout => 25,
raw_pty => 1,
);
my $login_output = $ssh->run_ssh or die "Could not launch SSH\n";
$ssh->waitfor('The authenticity of host*',15);
#print "This output for machine $machine\n";
$ssh->send("yes");
$ssh->waitfor('password: ', 15);
$ssh->send("$passwordforuser");
$ssh->waitfor('$ ', 10);
my @commresult=$ssh->exec("uptime");
print $login_output;
print @commresult;
exit 0;
}
else {
die "Could not Fork()\n";
}
}
foreach(@childprocs){
waitpid($_, 0)
}
请帮忙。谢谢,nblu。
答案 0 :(得分:3)
您的脚本使用Net::OpenSSH::Parallel而不是Net :: SSH :: Expect。
同时连接的数量限制为10,以克服脚本中发生的任何资源耗尽问题(可能是PTY):
#!/usr/bin/perl -w
use Net::OpenSSH::Parallel;
use Term::ReadKey;
print "please enter filename:\n";
$filename = ReadLine;
chomp $filename;
print "please enter user ID:\n";
$userID = ReadLine;
chomp $userID;
print "please enter password:\n";
ReadMode 'noecho';
$passwordforuser = ReadLine 0;
chomp $passwordforuser;
ReadMode 'normal';
open READFILE,"<","$filename" or die "Could not open file listofmachines\n";
my @listofmachines = <READFILE>;
chomp @listofmachines;
my $pssh = Net::OpenSSH::Parallel->new(connections => 10);
$pssh->add_host($_,
user => $userID, password => $passwordforuser,
master_opts => [-o => 'StrictHostKeyChecking=no'])
for @listofmachines;
sub do_ssh_task {
my ($host, $ssh) = @_;
my $output = $ssh->capture('uptime');
print "$host: $output";
}
$pssh->all(parsub => \&do_ssh_task);
$pssh->run;
for my $host (@listofmachines) {
if (my $error = $pssh->get_error($host)) {
print STDERR "remote task failed for host $host: $error\n";
}
}
答案 1 :(得分:1)
默认情况下,远程ssh守护程序将并发ssh连接数限制为每个userid 10个。如果这对您来说是个问题,则需要更改服务器配置......
答案 2 :(得分:0)
也许您可以创建的流程数量有限制?你可以在一个孩子刚睡觉的循环中创建30个或更多的进程吗(60)?
如果您实际上限制了一次可以执行的操作数量,请尝试使用Parallel::ForkManager。
如果这是对伪终端的限制,你如何设置它取决于内核版本; uname是什么意思?还取决于代码是使用BSD还是SysV / UNIX98 ptys。如果你看到它打开像/ dev / ptyXY这样的文件,其中X是a-e或p-z之一,那么它就是前者,你将有一个256系统的硬限制。
您可以使用usermod
而不是passwd
在没有伪终端的情况下更改密码,但这会暂时在流程列表中公开加密的密码;在你的情况下可能是可以接受的。