sunckell wrote:
Hello Perl People....

      I was wondering if someone could enlighten me on an observation I
have been seeing..

A little Background info:
      Where I work we have been seeing very slow ssh connections times
(it's not DNS.  Maybe NIS, NFS, but definitely not DNS).

       Anyways I wanted to write a script that would log the time it
takes to connect to a remote server via ssh and issue a command (uname
-n).  The tricky part was that I wanted the remote connections to kick
off every 60 secs.  (some ssh connections take a lot longer.  120+ in
some cases).  The log should enable me to pinpoint any time
correlation to the long ssh connect occurrences (every 5 minutes?  1/2
past every hour? etc).

      So here we are back to the script..  The script works as
expected, with one item of strangeness.  I was expecting the log
messages to be printed in the order they complete. For example, if the
connection attempt at 12:01 took 75 seconds to return, and the
connection attempt at 12:02 to 5 seconds to return, I would expect the
12:02 message to appear first then the 12:01, but it doesn't.  The
12:02 connection won't print until the 12:01 returns.

Here is my code:

use strict;
use Getopt::Std;
use Sys::Hostname;
use File::Basename;
use Net::SSH qw( sshopen2 );
use Time::HiRes qw( gettimeofday tv_interval );
$|++;

$SIG{CHLD} = 'IGNORE';

my %opts;
getopts('dr:', \%opts);

my $localhost = hostname();
my $r_host    = $opts{'r'} ? $opts{'r'} : die "need remote host<-r>
\n";

That is usually written as:

my $r_host    = $opts{ r } or die "need remote host<-r>\n";


my $debug     = $opts{'d'};
my $short_name = basename("$0", ".pl");

# --- set the counter to zero.  We'll print the counter to the log for
easier sorting
# --- of data where the ssh connections take longer than a minute to
return.
my $ct = 0;

while (1) {

     my $pid = fork();

     if ($pid) {
         # parent
     } elsif ($pid == 0) {
         # child
         my $p = _initialize($ct);
         waitpid($p, 0);
         exit 0;
     } else {
         die "couldnt fork: $!\n";
     }

That won't work correctly if fork returns undef and sets $! because undef in numerical context is the same as 0.

$ perl -le'print "undef is ", undef == 0 ? "" : "NOT ", "equal to 0"'
undef is equal to 0

And without warnings enabled you won't catch this mistake.

See:

perldoc perlipc

For how to verify that fork() worked correctly.


     $ct++;
     sleep 60;
}

# ---
# --- sub:     initialize
# --- descr:   for easier viewing of the code for the fork process.
# --- returns: nothing
# ---
sub _initialize{
     my($count) = @_;

     my $now    = scalar localtime();

"my $now = " forces scalar context on the right hand side of the assignment so the use of "scalar" is redundant.


     my $start   = [gettimeofday()];

     my $ret = connect_to_remote_host("$r_host");

     my $elapsed = tv_interval( $start );

     if ($count<  10){
         $count = "0$count";
     }

     if ($count<  99){
         $count = "0$count";
     }

That is usually performed with sprintf:

$count = sprintf '%03d', $_[ 0 ];


     my $msg =  "$count - [$now] $localhost to $r_host Elapsed time:
$elapsed ";
     write_to_log($msg);

     return;

}



John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction.                   -- Albert Einstein

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to