Perl脚本不能超过10次

时间:2012-10-22 19:51:11

标签: perl fork perl-module

我的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。

3 个答案:

答案 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在没有伪终端的情况下更改密码,但这会暂时在流程列表中公开加密的密码;在你的情况下可能是可以接受的。