3

私の perl コードでは、10 個を超えるフォークが許可されていません。次の perl コードでは、スクリプトに読み込まれたマシンのリストで 10 台を超えるマシンを使用すると、perl スクリプトは 10 台のマシンに対して 10 個のプロセスのみをフォークし、残りのプロセスはエラーで終了します。

SSHProcessError ssh プロセスが終了しました。serverLogin.pl 44 で $ssh->waitfor('ホストの信頼性*',15); と書かれている行で停止します。

パールスクリプト:

#!/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。

4

3 に答える 3

3

Net::SSH::Expect の代わりにNet::OpenSSH::Parallelを使用するスクリプト。

同時接続数は、スクリプト (おそらく PTY) で発生するリソース枯渇の問題を克服するために 10 に制限されています。

#!/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";
    }
}
于 2012-10-23T08:38:55.843 に答える
1

デフォルトでは、リモート ssh デーモンは同時 ssh 接続の数をユーザー ID ごとに 10 程度に制限します。それが問題になる場合は、サーバー構成を変更する必要があります...

于 2013-02-08T22:13:42.237 に答える
0

おそらく、作成できるプロセスの数に制限がありますか?子供たちが寝るだけのループで30以上のプロセスを作成できますか(60)?

実際に一度に実行できる数に制限がある場合は、Parallel::ForkManagerを使用してみてください。

これが疑似端末の制限に達したことが原因である場合、それをどのように設定するかはカーネルのバージョンによって異なります。uname -aは何と言いますか?また、コードがBSDまたはSysV /UNIX98ptysのどちらを使用しているかによっても異なります。Xがaeまたはpzのいずれかである/dev/ ptyXYのようなファイルを開いているのを見ると、それは前者であり、システム全体で256のハード制限があります。

usermodの代わりにを使用して、疑似端末なしでパスワードを変更できますpasswdが、これにより、プロセスリストに暗号化されたパスワードが一時的に公開されます。それはあなたの場合には受け入れられるかもしれません。

于 2012-10-22T20:45:46.730 に答える