Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: Need Help in running Expect script in Perl

by jffry (Hermit)
on Mar 12, 2012 at 22:07 UTC ( [id://959195] : note . print w/replies, xml ) Need Help??


in reply to Solved: Need Help in running Expect script in Perl

First, it has been a while since I've used CPAN Expect, so my advice may not be accurate.

Second, I want to clarify your problem. You are saying that when output gets here:

SWBKPT hit for SLOT 1..!! PC-Value : 0x124 Blk Count = 1 Cycles +: 332

...your Perl script does not seem to send the "\n" so that the console program will continue.

I see two potential problems. One, you have really short timeouts (2 seconds). Two, you are expecting "SWBKPT hit for SLOT" but some text is still being output after that match. Thus, it is possible the "\n" is being sent before the console program is reading input and the "\n" send is not buffered.

To help debug, try calling the expect() method in array context, then dump the array to see the status of the expect() call.

use Data::Dumper; my @exp_stat; @exp_stat = expect "SWBKPT hit for SLOT"; print Dumper(\@exp_stat);

And read this explanation from the CPAN Expect docs:

If called in an array context expect() will return ($matched_pattern_position, $error, $successfully_matching_string, $before_match, and $after_match).

$matched_pattern_position will contain the value that would have been returned if expect() had been called in a scalar context. $error is the error that occurred that caused expect() to return. $error will contain a number followed by a string equivalent expressing the nature of the error. Possible values are undef, indicating no error, '1:TIMEOUT' indicating that $timeout seconds had elapsed without a match, '2:EOF' indicating an eof was read from $object, '3: spawn id($fileno) died' indicating that the process exited before matching and '4:$!' indicating whatever error was set in $ERRNO during the last read on $object's handle. All handles indicated by set_group plus STDOUT will have all data to come out of $object printed to them during expect() if log_group and log_stdout are set.

Replies are listed 'Best First'.
Re^2: Need Help in running Expect script in Perl
by subhasishn@yahoo.com (Initiate) on Mar 13, 2012 at 10:00 UTC

    I tried debugging as advised

    Here is the output

    Use of uninitialized value $pattern_list[1] in print at try_expect.pl +line 24. 1SWBKPT hit for SLOT 1..!! PC-Value : 0x124 Blk Count = 1 Cycles + : 332 sproc1>loadprg a.out Endianness of the ELF file:0 .text matched [text segment] flag = 0x3 .ctors matched [data segment] flag = 0x3 .dtors matched [data segment] flag = 0x3 .data matched [data segment] sproc1>run Run mode selected Buffer Empty = 32 Buffer Empty = 32 Buffer Empty = 32 Buffer Empty = 32 Buffer Empty = 28 Expect=GLOB(0xa088960)

    Now if am not wrong then $pattern_list1 should give me the value that would have been returned if expect() had been called in a scalar context. But its shows uninitialized. Now how should I set an expect for nothing....Help please

      I'm assuming you're using @pattern_list to hold the return values from expect() like this:

      @pattern_list = expect "SWBKPT hit for SLOT";

      If that is true, then $pattern_list[0] is the "matched pattern position", $pattern_list[1] is the "error" and $pattern_list[2] is the "successfully matching string". However, to debug this, we need all the values, which is why I asked you to use Data::Dumper.

      If you want to print the array values without Data::Dumper, then do something like this:

      my @arr = qw( bob sue jane); print "\@arr = " . join(':', @arr) . "\n";
      Run example:
      my@mybox:~/sandbox $ ./4.pl @arr = bob:sue:jane

      The reason all the values are important is because if $pattern_list[4] ("after match") has a value, then that probably means Expect is sending the "\n" before your console program is reading input.

      Actually, you know what would be a quicker test of that? Insert a sleep() between your expect() and send() like this:

      $expect->expect($timeout,"SWBKPT hit for SLOT"); sleep 2; $expect->send("\n\n");

      Of course, this test assumes that it takes less than 2 seconds between when the console program prints "SWBKPT hit for SLOT" and when it prints "Cycles : 332".

        Here is the Output with Data::Dumper

        I have also given the script below

        nandi@nandi-laptop:~/begperl$ perl try_expect.pl Selecting sproc1 CPU sproc1> sproc1>loadprg a.out Endianness of the ELF file:0 .text matched [text segment] flag = 0x3 .ctors matched [data segment] flag = 0x3 .dtors matched [data segment] flag = 0x3 .data matched [data segment] sproc1>run Run mode selected Buffer Empty = 32 Buffer Empty = 32 Buffer Empty = 32 Buffer Empty = 32 Buffer Empty = 28 SWBKPT hit for SLOT 1..!! PC-Value : 0x124 Blk Count = 1 Cycles +: 332 $VAR1 = [ 1, undef, 'SWBKPT hit for SLOT 1..!! PC-Value : 0x124 Blk Count = + 1 Cycles : 332', 'loadprg a.out Endianness of the ELF file:0 .text matched [text segment] flag = 0x3 .ctors matched [data segment] flag = 0x3 .dtors matched [data segment] flag = 0x3 .data matched [data segment] sproc1>run Run mode selected Buffer Empty = 32 Buffer Empty = 32 Buffer Empty = 32 Buffer Empty = 32 Buffer Empty = 28 ', ' ', bless( \*Symbol::GEN0, 'Expect' ) ];

        $VAR1 shows that the pattern has matched in 1 poition ie 0 postion of my @match array

        undef indicating no error

        then comes the successfully_matching_string

        then comes the before_match

        finally after_match... But here the after match is empty.. So i gussed it must be "\n"

        To verify that i did a print with Match_after in between "Hello World"

        As it comes out my guess was right

        So expect is sending "\n\n" before simulator finishes execution. So I put a sleep as advised.. :( Didnt work either

        Here is the script..

        #!/usr/bin/perl use warnings; use strict; use Expect; use Data::Dumper; chdir '/home/nandi/simulator/' or die "Can't change directory : $!"; my $expect = Expect->new; my $command = './simulator/pruthvi.out'; my @parameters = qw(-m 4); my $timeout = 2; my @pattern_list; my @match = "SWBKPT hit for SLOT 1..!! PC-Value : 0x124 Blk C +ount = 1 Cycles : 332"; $expect->spawn($command,@parameters ) or die "Cannot spawn : $!\n"; $expect->expect($timeout,"Selecting sproc1 CPU"); $expect->send("\n\n"); $expect->expect($timeout,"sproc1>"); $expect->send("loadprg a.out\n"); $expect->expect($timeout,'sproc1>'); $expect->send("run\n"); @pattern_list = $expect->expect($timeout,@match); print Dumper(\@pattern_list); #$expect->expect($timeout,"SWBKPT hit for SLOT"); #my $match_after = $expect->after(); #print "Hello $match_after World"; sleep 3; $expect->send("\n\n"); #$expect->expect("sproc1>"); #$expect->send("dump mem 74010 4 \n"); #$expect->expect("sproc1>"); #$expect->send("quit\n");

        Now what I am supposed to do.. I entered "\n" at the end of string in @match but that too didnt work out.

        I think CPAN Expect is not that friendly with Perl compared to Shell. I have no problem running expect in SHELL script.

        Hi je44ery I made it.. The script works like charm now..

        Thanks for all your valuable input, suggestion, patience and time

Re^2: Need Help in running Expect script in Perl
by subhasishn@yahoo.com (Initiate) on Mar 13, 2012 at 05:06 UTC

    Thanks for your reply. I appreciate it.

    I thought the same.. so I had tried the script with longer timeout(100 sec) as well didnt work out. Then I replaced the output completely as I was receiving from my simulator. That too didnt work out.

    Is there any work around other than CPAN Expect

    As suggested I will try to debug and try again