Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Re: Expect doesn't work as Expected

by jethro (Monsignor)
on Jul 07, 2012 at 21:38 UTC ( #980521=note: print w/replies, xml ) Need Help??

in reply to Expect doesn't work as Expected

Your regexp .* is the biggest problem here. .* matches everything, even the empty string! The module goes into an endless loop always matching the empty string and never advancing because nothing is matched or rejected, so new match rounds start at the same place.

If you want to see how it works, change .* to .+ in your original script. Then you will see how it works and you will see sensible values printed for "after match string" and "before match string"

I could get your script to work (although endlessly) by adding \n to your ->send strings and disabling your .* catch all or nothing regexp:

#!/usr/bin/env perl use Expect; #$Expect::Debug = 3; # verbose debug output #$Expect::Log_Stdout = 1; # show chatter for debugging #$Expect::Exp_Internal =1; my $exp = Expect->spawn("units") or die "Cannot spawn unit: $!\n"; $exp->log_stdout(1); $exp->expect(15, [ qr/you have/i => sub { my $exp = shift; #print "you have"; $exp->send("2 km\n"); exp_continue; } ], [ qr/you want/i , sub { my $exp = shift; #print "you want"; $exp->send("m\n"); exp_continue; }], [ 'eof', sub { my $exp = shift; print "eof"; print +$exp->before(); } ], [ qr/blabla.*/, sub { my $exp = shift; print $exp->error; print $exp->before(); exp_continue; } ] );

I suspect you will never get an 'eof' because units runs in an endless loop. You have to send the eof or control-d character to units or simply close the connection when the regexp /you have/ matches a second time, i.e. something like this works:

[ qr/you have/i => sub { my $exp = shift; if (++$counter<=1) { $exp->send("2 km\n"); exp_continue; } else { $exp->soft_close(); + } } ],

PS: Please use 'use warnings;' and 'use strict;'. No modern perl script is complete without them

Replies are listed 'Best First'.
Re^2: Expect doesn't work as Expected
by keenlearner (Acolyte) on Jul 08, 2012 at 06:45 UTC


    Thanks for your help, I added that .* after when I find it does not work, just would like to see if the Expect got any input from the terminal.

    I realize it's okay if I execute the perl code from terminal.

    But it does not work if I use modperl executed in apache. It will always return eof without any match. Any suggestion for this ?


      You should use $exp->log_file to log the debug output to a file instead of to STDOUT while running the script in apache. Look for differences in the log to what you see in the log when you execute it on the command line/terminal

      Getting eof probably means that the mod_perl version of the script doesn't get any output from the units script. Do you see the output maybe in your browser page (highly unlikely)?

      Very important: Check apache log files for any hints of what is happening

      Expect FAQ says this:

      Is it possible to use threads with Expect?

      Basically yes, with one restriction: you must spawn() your programs in the main thread and then pass the Expect objects to the handling threads. The reason is that spawn() uses fork(), and perlthrtut:

      "Thinking of mixing fork() and threads? Please lie down and wait until the feeling passes."

      If your apache uses threads instead of forks, this might be a problem. I'm not sure about apache, on linux it should probably use fork (if you do "ps -ef" on the command line, you should see multiple lines with "httpd" or "apache"). On windows it probably uses threads

      As a test you could change the execution of "units" to a simple "echo you have" and look at the log output. If that changes anything your apache seems to have problems executing units. But then you should have found out about this in the log files, so this test is just to make double sure it is not the units program that is the problem

      You could ask the mailing list mentioned in the documentation (expectperl-discuss) if they know whether expect is generally working or not working in mod_perl

        Hi Thanks for your help,

        Basically yes, with one restriction: you must spawn() your programs in the main thread and then pass the Expect objects to the handling threads.

        I will try that

        and will ask the mailing list once I got the time.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://980521]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (2)
As of 2017-09-24 12:34 GMT
Find Nodes?
    Voting Booth?
    During the recent solar eclipse, I:

    Results (274 votes). Check out past polls.