Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Processing data from SSH stream

by Spasticus (Initiate)
on Apr 12, 2007 at 00:19 UTC ( [id://609533]=perlquestion: print w/replies, xml ) Need Help??

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

Hi All, I'm an inexperienced perl coder and could really use some help here.

I'm trying to connect to a series of machines via ssh, call a script on each that returns formatted data and process the data in turn. This sub is used to retrieve the data from each machine and store it in a hash...

sub get_remote_file { print "Retrieving data file..."; my @site_data; chomp( @site_data = `$conx` ); if ( $? >> 8 ) { print "Failed!\n"; } else{ print "Success!\n"; } for $line( @site_data ) { ( $name, $filepath, $mod, $md5 ) = split( "\,", $line ); $site_data{$name} = ["$filepath", "$mod", "$md5"]; } @site_data = (); }
Which is called from within:
foreach $client ( @clients ) { my ( %site_data, %office_data ); print "Performing Sentinel check on $client\n"; get_client_configs( $client ); print "Retrieving data from site...\n"; get_remote_file; generate_local_data; compare_files; print "Completed Sentinel check on $client\n"; }

get_client_configs updates the $conx variable among other things. The $conx variable holds the connection string, eg 'ssh host ~/myscript'.

The problem I'm having is that the first time through the loop everything works fine and the hash is properly populated. However on every subsequent call the @site_data ends up with a single element containing all the data returned from the script on the remote machine. As you can see it screws up the populating of the hash.

Can anyone please help? Before you say it I cannot install any modules to help with this, it's not my machine.

Replies are listed 'Best First'.
Re: Processing data from SSH stream
by roboticus (Chancellor) on Apr 12, 2007 at 09:46 UTC
    Spasticus:

    Just an observation: You may want to spend a few minutes and come up with some better variable names. Specifically, you're using both %site_data and @site_data which can be somewhat confusing for future maintenance--especially when both are used in the same subroutine.

    ...roboticus

Re: Processing data from SSH stream
by Anonymous Monk on Apr 12, 2007 at 03:57 UTC
    I use perl and perl-expect to do this sort of thing. It can get very complex, but using expect to control the SSH session and allow error handling it will do what you want. There was once a program out there called remote_update-1.6 by Viraj Alankar that I was very impressed with. For my uses I had to totally rewrite it to meet my needs but it will get you where you need to be.
      Thanks mate, I'll look into it.
Re: Processing data from SSH stream
by Krambambuli (Curate) on Apr 12, 2007 at 10:13 UTC
    Just an idea, to maybe come closer to the problem, try to
    use Data::Dumper;
    somewhere early in your script and add some debugging aids into the problematic sub, like
    sub get_remote_file { print "Retrieving data file..."; my @site_data; print Dumper( $conx ); chomp( @site_data = `$conx` ); print Dumper( @site_data ); if ( $? >> 8 ) { print "Failed!\n"; } else{ print "Success!\n"; } for $line( @site_data ) { ( $name, $filepath, $mod, $md5 ) = split( "\,", $line ); $site_data{$name} = ["$filepath", "$mod", "$md5"]; } @site_data = (); }
    Maybe that reveals something that would explain the different behavior of the first run compared with the subsequent ones.
      Thanks for all your help people :)
      I eventually found the problem - totally unrelated to SSH file properties. It turns out that in processing the retrieved data from the stream that in some instances I had to undef $/. Unfortunately I forgot to redefine it afterwards. This explains why it was working for the first file processed and failing for each one after.
      Again, thanks for your help :)
        Btw, it's a good habit to use local to restrict the scope of modifications to special variables such as $\.

        An example from the perlvar doco:

        my $content = ''; open my $fh, "foo" or die $!; { local $/; $content = <$fh>; } close $fh;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://609533]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-04-24 13:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found