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

Hi

I'm currently using the Net::SSH module to get some info off of some other machines, and then I display it on a webpage via apache. I've come to realize that if SSH fails for whatever reason (can't reach the machine, or permission denied) that the script exits and prints the error (from stderr?) right there on the page. It's ugly, and the script won't finish. I figured this would work, but doesn't.
my $ssh = Net::SSH::Perl->new( $server ); if ( $ssh->login( "user", "pass" ) ) { my ( $stdout, $stderr, $exit ) = $ssh->cmd("ps -ef |grep \"$proc\ +" |grep -v grep"); } else { print "ERROR"; }

I basically want it to go on about it's business if it can't login for whatever reason, but it doesn't. It dies, and prints the error out on the page. Anyway around this?

Replies are listed 'Best First'.
Re: Net::SSH question
by ptum (Priest) on Nov 24, 2005 at 00:40 UTC
    The most obvious problem I see is that you talk of using Net::SSH but then refer to Net::SSH::Perl. Those are two different packages.

    Have you considered placing your ssh connection inside an eval block?

    No good deed goes unpunished. -- (attributed to) Oscar Wilde
      Sigh. Too bad I don't read the manual. I tried putting a simple ssh connection inside eval and discovered it didn't trap STDERR, as it says in http://www.perl.com/doc/manual/html/pod/perlfunc/eval.html. Sorry for the bad advice.

      "Beware that using eval() neither silences perl from printing warnings to STDERR, nor does it stuff the text of warning messages into $@. To do either of those, you have to use the $SIG{__WARN__} facility. See warn and the perlvar manpage."

      No good deed goes unpunished. -- (attributed to) Oscar Wilde
        ptum:

        You are right, it's Net::SSH::Perl I'm using, but I had lost my browser window by the time I had figured it out, and don't know how to edit the original post until there have been replies to it.

        Anyways, I can probably avoid this problem if I can figure out how to use the other authentication methods. AFAIK, it's using rhosts... the server in question though, has IgnoreRhosts set to "yes", so that won't work. Nobody will have access to this script, so I really just want to do password authentication, but can't find in the docs (or any other pages) on how to sort that out.

        Thanks for the effort thusfar. EDIT: No, it's not reading rhosts. O_o I guess I need to fix the sshd_config file on the server then.
Re: Net::SSH question
by u235sentinel (Hermit) on Nov 24, 2005 at 06:13 UTC
    I had the same problem when I started experimenting with Net::SSH. I noticed they did this on purpose in their module after a little digging :-)

    How I resolved it was to write code to test port 22 if it was alive using IO::Socket. Seemed to work pretty good. Any system that failed the IO::Socket test I skipped connecting to in SSH. I also logged to a failed file so I knew which systems I failed to connect to. Basically working around their design. This way I knew which failed and I connected with everybody else without bombing.

    Does this help? If not let me know. I'll try to explain it better :D
      Yes, that explains it quite well. This will work in every situation except for failed authentication. Worth noting though... I'll try to sort something out. Thanks for the info.
Re: Net::SSH question
by Cody Pendant (Prior) on Nov 24, 2005 at 04:10 UTC
    If you want it not to print the error message, I think this could be where you're going wrong...
    else { print "ERROR"; }
    Try removing that part of your script.


    ($_='kkvvttuu bbooppuuiiffss qqffssmm iibbddllffss')
    =~y~b-v~a-z~s; print
      I actually just added that to test the conditional (which doesn't work). It doesn't print "ERROR", although it'd be great if it did. It prints "Permission Denied" --what I believe is stderr... something I don't want. :(