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

Hello Monks,

I am using the Expect module to connect to a list of servers to gather information (output of metastat -p, dumpadm, etc) for a report. It seems to be working fine, however occasionally (not even for each server or command) I will get a prompt embedded in my output. For example:
server1: d102 -m d4 1 - Not Mirrored server1: d101 -m d2 1 - Not Mirrored server1: d100 -m d0 1 - Not Mirrored server1: d104 -m d8 1 - Not Mirrored server2: server2:user> d104 -m d8 1 - Not Mirrored server2: d103 -m d6 1 - Not Mirrored server2: d102 -m d4 1 - Not Mirrored server2: d101 -m d2 1 - Not Mirrored server2: d100 -m d0 1 - Not Mirrored server3: server3:user> metastat: server3: there are no existing datab +ases - Not Mirrored server3: - Not Mirrored

I add the ' - Not Mirrored' part, but for the commands in there, the server2:user> prompt gets stuck in there. I understand why it occurs when the command fails (ie for the one on server3 where there are no existing databases -- that is the output of the command) but not for the one for server2 where the command returns the same output as it did for server1. Hopefully my question makes sense. I'm relatively new to the Expect module, so I'm still getting a feel for it.
If anyone wouldn't mind enlightening me as to why the prompt only sometimes gets dumped to the output, and how to prevent it, I'd appreciate it!
Thanks!


Update: I just realized I could resolve this one way by prepending a PS= ; on the beginning of my command to temporarily blank the prompt. If there is a better way, I'd love to hear it. Thanks!

Replies are listed 'Best First'.
Re: Net::SSH::Expect output
by Illuminatus (Curate) on Jul 23, 2009 at 16:12 UTC
    Code?
      The first part checks for the filesystem type.. zfs - do nothing, since it doesn't use SVM... the 2nd part of the if statement processes the ufs part, by running metastat -p and counting the number occurrences of the letter d... for a mirror with 2 plexes it should be 3, one for the metadevice, and one for each plex. Anything less than 3 gets thrown out as being unsynched. The $mirror_cmd is the metastat -p |grep m to get the metadevices only.

      Here is the while loop for that part of the code:
      while ( defined ($line = $ssh->read_line()) ) { if($line =~ m/zfs/) { open(MIR,">>$MIRRORS"); print MIR "$_ - has ZFS root, no metadevices e +xist\n"; close(MIR); } else { # Not ZFS, presumably ufs # Execute SVM Mirror check - looking for unsyn +ched mirrors my $mirror_output = $ssh->send("$mirror_cmd"); my $line2; while ( defined ($line2 = $ssh->read_line()) ) + { my $tmpcount = ($line2 =~ tr/d//); if($tmpcount < 3) { open(MIR,">>$MIRRORS"); print MIR "$_: "; chomp(); print MIR "$line2 - Not Mirror +ed\n"; close(MIR); } } } }

      On a side note, apparently setting PS = ; had no effect, because it's still showing the same output as earlier.

      Thanks!

        This doesn't look like expect code. It looks like regular old read-the-file-regex-output code. So, you may be missing the cool expect features.

        I have a guess: ssh and Expect can't really know what's prompt and what's command output. It's all a stream on stdout. You probably have to clear a buffer or something like that after you log in but before you run the command. It's significant that it's the 1st line on server2, because that's what you'd expect to see if you logged in and typed a command.

        Does it always happen on server2? If so, it might be a shell setting specific to that account and that server.

        Finally, you could just regex out the prompt from the input. You don't need to worry about speed so an extra regex on each line won't hurt anyone.

        Really Finally, you could scrap SSH::Expect and use ssh with public keys instead of passwords. That might set up the environment better and not show you the prompt. Since you're not really using the expect features, that might be an easier way to go.

Re: Net::SSH::Expect output
by salva (Canon) on Jul 24, 2009 at 09:59 UTC