Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

How can I show all input and output with Expect.pm

by GeorgeAdams (Initiate)
on Oct 06, 2014 at 21:17 UTC ( [id://1103014]=perlquestion: print w/replies, xml ) Need Help??

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

Here is a little Perl server script. It displays (1), accepts a line of input, then displays (2), etc. If you type "error" or "commit", it gives a custom message. If you type "exit", it quits. Otherwise, it just endlessly takes lines of input.

use strict; use warnings; $|++; my $counter = 1; print "($counter) "; while (<STDIN>) { chomp; if ($_ eq "error") {print "Error on command #$counter\n";} if ($_ eq "commit") {print "Committing data\n";} if ($_ eq "exit") {print "Exiting program...\n"; exit;} $counter++; print "($counter) "; }

Now, here is an Expect.pm client script to interact with the server script by typing in various lines.

use strict; use warnings; use Expect; $|++; my $exp = new Expect; $exp->raw_pty(1); $exp->log_file("/tmp/expect.out"); $exp->log_stdout(1); my @commands = ( "This is the first command", "Here is the second command", "error", "commit", "This is the last command", "exit", ); $exp->spawn("./expecttest_server.pl"); foreach my $command (@commands) { print "$command\n"; $exp->send("$command\n"); $exp->expect(1, '-re','\(\d+\)'); } $exp->soft_close();

What I want is to be able to store the entire session from start to finish, including everything the server script generated, and everything the Expect.pm script sent.

It should look like this:

(1) This is the first command
(2) Here is the second command
(3) error
Error on command #3
(4) commit
Committing data
(5) This is the last command
(6) exit
Exiting program...

But the STDOUT display that comes from running the client script looks like this:

This is the first command
(1) (2) Here is the second command
error
(3) Error on command #3
(4) commit
This is the last command
Committing data
(5) (6) exit
Exiting program...

and the file specified by $exp->log_file (tmp/expect.out) shows this:

(1) (2) (3) Error on command #3
(4) Committing data
(5) (6) Exiting program...

I've tried experimenting by logging various combinations of the command itself + the before_match and after_match variables returned by $exp->expect(). But so far I haven't gotten the right combination. And it seems like an awfully clunky way to get what I'm looking for.

So, what's the best practice for capturing the entirety of an Expect.pm session?

Thanks to anyone who can help!

Replies are listed 'Best First'.
Re: How can I show all input and output with Expect.pm
by frozenwithjoy (Priest) on Oct 06, 2014 at 22:02 UTC

    I see two main problems.

    First, the following lines are in the wrong order for what you want your output to be:

    print "$command\n"; $exp->send("$command\n"); $exp->expect(1, '-re','\(\d+\)');

    You probably want this order instead:

    $exp->send("$command\n"); print "$command\n"; $exp->expect(1, '-re','\(\d+\)');

    Second, this:

    my $counter = 1; print "($counter) ";

    Should just be this:

    my $counter = 0;

    The extra stuff is just junk since you print and increment the counter in your loop. This change will fix printing 1 and 2 together like you observed here: (1) (2) Here is the second command

    EDIT: Hmmm. Looking at your scripts more closely, I'm having second thoughts about this. What if you just print it all from the server script? Like this:

    while (<STDIN>) { chomp; $counter++; print "($counter) $_\n"; if ($_ eq "error") {print "Error on command #$counter\n";} if ($_ eq "commit") {print "Committing data\n";} if ($_ eq "exit") {print "Exiting program...\n"; exit;} }

      @frozenwithjoy, thanks for the reply. To answer your questions:

      1. It doesn't seem that reversing the order of the commands
        print "$command\n";
        $exp->send("$command\n");
        
        makes any difference either to the STDOUT or logfile output. It still gives:
        (1) (2) Here is the second command
        error
        (3) Error on command #3
        (4) commit
        This is the last command
        Committing data
        (5) (6) exit
        Exiting program...
        
      2. The server script has to print out the "(1) " before it receives any input. When it gets a line, it simply prints out "(2) " , waits for the next line, prints "(3) ", waits for the next line, etc. The code isn't optimized, but that's at least the explanation of why the $counter = 1 and the first print statement comes before the loop.

        That is, if you ran the server script and entered stuff, you'd get:

        (1) This is the first line I typed.  Now I'm hitting <ENTER>
        (2) I'm typing more stuff.
        (3) exit
        Exiting program...
        
      3. Good question. The server script is actually representing what I cannot control in this. It may be a company-wide program I'm trying to interact with, or a Juniper router, or an IDS box, or probably a lot of other things. So unfortunately for this example I have to pretend that I can't modify the server's output. All I can do is interact with the (program, router, server, etc.) myself, see what it outputs when I interact with it manually, then try to reconstruct that exact output when my Expect.pm script interacts with the (program, router, server, etc.) in the same way.
Re: How can I show all input and output with Expect.pm
by choroba (Cardinal) on Oct 06, 2014 at 21:50 UTC
    Crossposted at StackOverflow. It's considered polite to inform about crossposting so that people not attending both sites don't waste their efforts hacking a solution to a problem already solved at the other end of the Internet.
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (6)
As of 2024-04-18 06:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found