walkingthecow has asked for the wisdom of the Perl Monks concerning the following question:

Hey Monks!

I am trying to figure out how to combine the following code so that I do not have to call another script. Currently, the following code works. For 4,000 servers it will spawn 25 child processes at a time. Each child process will log into the server assigned, then get the uname information. However, if I try to combine the code I get the following error: "Cannot start another process while you are in the child process..."

It's not that big a deal if I have to do it with two different scripts, but was just trying to figure out if there was a way to do it all in one. The first two code blocks are the ones that work, and the third code block is the non-working attempt at combining.

#!/usr/bin/perl use strict; use FindBin qw ($Bin); use lib "$Bin/lib"; use ForkManager; use General; use Benchmark; getPassword("Please enter your password: "); my $start = new Benchmark; open SERVERS,"$ARGV[0]" or die $!; my (@hosts)=<SERVERS>; close SERVERS; my $sshscript = "checkUname.pl"; my $maxProbes = 20; # set this to one to do one at a time my $pm = new ForkManager($maxProbes); foreach my $hostname (@hosts) { $pm->start and next; my $stdout = `./$sshscript $hostname`; print "$stdout\n"; $pm->finish; } $pm->wait_all_children; print "done\n"; my $end = new Benchmark; my $diff = timediff($end, $start); print "Time taken was ", timestr($diff, 'all'), " seconds";


#!/usr/bin/perl use strict; use FindBin qw ($Bin); use lib "$Bin/lib"; use General; use Functions; my $host=$ARGV[0]; $General::password=$ENV{'PASSWORD'}; my $login = getPrompt($host); die "Could not connect to $host" if $login ne "SUCCESSFUL!"; my $result = getOSType(); print $result;


#!/usr/bin/perl use strict; use FindBin qw ($Bin); use lib "$Bin/lib"; use ForkManager; use General; use Benchmark; getPassword("Please enter your password: "); my $start = new Benchmark; open SERVERS,"$ARGV[0]" or die $!; my (@hosts)=<SERVERS>; close SERVERS; my $sshscript = "checkUname.pl"; my $maxProbes = 20; # set this to one to do one at a time my $pm = new ForkManager($maxProbes); foreach my $hostname (@hosts) { $pm->start and next; #my $stdout = `./$sshscript $hostname`; my $login = getPrompt($hostname); next if $login ne "SUCCESSFUL!"; my $stdout = getOSType(); print "$stdout\n"; $pm->finish; } $pm->wait_all_children; print "done\n"; my $end = new Benchmark; my $diff = timediff($end, $start); print "Time taken was ", timestr($diff, 'all'), " seconds";

Replies are listed 'Best First'.
Re: Simultaneous SSH sessions with Parallel::ForkManager + Expect
by 5mi11er (Deacon) on Mar 26, 2009 at 21:59 UTC
    There's nothing inherent about SSH that will keep you from running more than one command at a time. But calling ssh with a command executes the command and then exits, I'm guessing that's what you are doing when you call the perl command, so the connection is gone by the time you try to call the getOSType function in the "combined script".

    Since getOSType and getPrompt aren't provided above, all we can do is guess at what's going on, which makes the probability of getting helpful answers drop close to zero.

    -Scott

Re: Simultaneous SSH sessions with Parallel::ForkManager + Expect
by ladyphnx (Novice) on Mar 27, 2009 at 14:24 UTC
    I am still much the padawan-learner Monk, but I'm going to offer what I have in hopes it may help.

    I've never used ForkManager before, but it looks to me like you're getting that error because if $login ne "SUCCESSFUL!", then you never get to $pm->finish; You could change this if you reverse your test...

    Try this:

    if $login eq "SUCCESSFUL!" { my $stdout = getOSType(); print "$stdout\n"; }
    and let me know what happens. :)