http://www.perlmonks.org?node_id=58634
Description: If you have ever used Expect to execute commands on a remote system I am sure you have run into the problem of parsing the command output from the output of the Expect methods exp_before(), clear_accum(), etc... . If you send your command to this subroutine it will parse the output for you and return the command output as it would be returned from a backtick execution. Note: This subroutine uses a global Expect object variable which already has an established connection. The subroutine will not take commands that end in & .. for those commands just use $expect->print method.
# Executes a command via a global expect object and
# returns the output of the command.
#
# Arguments:
#       1 - Command     <string variable containing the command string
+>
# Returns:
#       String variable cotaining the output of the specified command.
#

sub expect_execute($) {
        $expect->clear_accum();
        my $command = shift;
        my $x = '';
        my $temp = '';
        if ( $command =~ /;$/ ) {
                chop( $command );
        }
        print $expect "$command | sed 's/^/COMMAND_OUT: /g'; echo -n E
+ND_; echo EXPECT\n";
        $expect->expect( 300, -re => '^END_EXPECT' );
        my $result = $expect->exp_before();
        ( my @result ) = split( /\n/, $result );
        $result = '';
        foreach $x ( @result ) {
                $temp = $x;
                if ( chop( $temp ) eq "\r" ) {
                        chop( $x );
                }
                if ( $x =~ m/^COMMAND_OUT: / ) {
                        $temp = substr( $x, 13 );
                        $result = $result . $temp . "\n";
                }
        }
        return $result;
}

Replies are listed 'Best First'.
Re: Expect command output parser sub
by vishi (Beadle) on Jan 03, 2012 at 07:20 UTC

    This is brilliant!!!! Thank you so much for this.. I've been fooling around with this issue for over a year and never found anything satisfactory.

    Here's what I was using so far... it does the job..but there was a need to match for a pattern anyway...

    $sshMTT1->clear_accum(); $sshMTT1->expect(10,[qr/\$[\s]*/=> sub {$sshMTT1->send("grep <<<<<<*PA +TTERN>*>>>>");}]); @Output = $sshMTT1->expect(5); $sshMTT1->send("\cC"); $exactOutput = $Output[3]; $exactOutput =~ tr/\cM//d;

    The variable $exactOutput had more or less the value I was looking for and I used to pattern match on this variable... Primitive.. compared to the solution here!!!

      This subroutine fails to execute the command if the executed command isn't supposed to return any value ( for example the cd command or mkdir command.

      For example if we try to execute the cd <XYZ_Directory> command using this subroutine, the directory change doesn't happen at all.

      Any help to make it fucntional for such commands is welcome

        Any help to make it fucntional for such commands is welcome

        I would say its impossible so don't use it on such commands, or append ";pwd" so they do print output

Re: Expect command output parser sub
by Anonymous Monk on Oct 26, 2007 at 09:54 UTC
    Great !!!!!!! You solved my problem.
      Thank you!!!! I've been trying to figure out how to determine completion of a command, your approach is clever. If we can't get a clear indication by command, we can just insert our own! Sweet!
        genius!! been looking for this for a few hours now...