Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[expect] how to match multiple times in one expect

4,694 views
Skip to first unread message

Sektor van Skijlen

unread,
Jul 29, 2004, 10:59:03 AM7/29/04
to
Hello,

Let's say, I have the following output in response to sent command:

=============================
DEVICE | STATE
=============================
LKS1 | ON
LKS2 | ON
LKS5 | ON
LKS6 | ON
-----------------------------

I'd like just to collect info about these "LKS".

There is a good recognizable "device entries" and "end of output",
definable by regular expressions.

How could the expect repeat "expecting" (and "stop expecting", when "end of
output" has been reached)? I used exp_continue, when recognizing the device
entry, but expect ate up one entry and gave up, though.

Of course, an alternative way is to look over the expect_out(buffer), but
I hope there is an easier way to do it.


--
1 6 1 7 4 4 2 548 g4bc7a4 66z 3xt7w v1y z9p1 120 32
(( Michal "Sektor" Malecki w4 66 64 73 7564 24 5 v 34 4
)) ektor van Skijlen 1 5 5 1 844 a v r z 4
Software engineer, Motorola GSG Poland 1 2 2a 1 4
WARNING: Opinions presented by me on usenet groups are my personal opinions
ONLY and are not connected to the employer.

Don Libes

unread,
Jul 30, 2004, 1:33:37 PM7/30/04
to
Sektor van Skijlen <sek...@hasiok.org> writes:

> Let's say, I have the following output in response to sent command:
>
> =============================
> DEVICE | STATE
> =============================
> LKS1 | ON
> LKS2 | ON
> LKS5 | ON
> LKS6 | ON
> -----------------------------
>
> I'd like just to collect info about these "LKS".
>
> There is a good recognizable "device entries" and "end of output",
> definable by regular expressions.
>
> How could the expect repeat "expecting" (and "stop expecting", when "end of
> output" has been reached)? I used exp_continue, when recognizing the device
> entry, but expect ate up one entry and gave up, though.

I would expect the code to be something like this:

expect {
-re "LKS(.) . (ON|OFF)" {
# take some action with expect_out and continue
exp_continue
}
-ex "-" {
# end of list, fall through to next command
}
}

Don

Sektor van Skijlen

unread,
Jul 31, 2004, 12:30:05 PM7/31/04
to
Dnia 30 Jul 2004 13:33:37 -0400, Don Libes skrobie:


Hmm... sounds interresting.

As I said, I tried using exp_continue, but this did not work. Was that because
I didn't use "-ex" option? (this time I can't verify it, unfortunately).

I tried also enclosing this expect in "while 1" loop with break in the
"finishing match". This also did not work as expected (I don't remember why).


--
// _ ___ Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl>
\\ L_ |/ `| /^\ ,() <ethourhs(O)wp.pl>
// \_ |\ \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx

Don Libes

unread,
Aug 2, 2004, 1:01:01 PM8/2/04
to

-ex merely describes the matching style ("exact" in this case). I
could've written it without the -ex but the pattern would be different.

> I tried also enclosing this expect in "while 1" loop with break in the
> "finishing match". This also did not work as expected (I don't remember why).

From your description, it sounds like your pattern may have matched
too much. That would explain your earlier complaint as well.

You may find it helpful to use the -d flag when you run Expect to see
what matches are being attempted.

Don

Sektor van Skijlen

unread,
Aug 4, 2004, 3:53:29 AM8/4/04
to

So thought I.

Or maybe the problem is because expect divides the incoming text for parts
in any other way than I thought? For example, the device I connect with
responses actually something like:

"> \r LKS1 | ON\r\n"

With this "> \r" each line is prepended.

> > I tried also enclosing this expect in "while 1" loop with break in the
> > "finishing match". This also did not work as expected (I don't remember why).

> From your description, it sounds like your pattern may have matched
> too much. That would explain your earlier complaint as well.

So maybe you would be able to explain me, why expect "remembers" previous
matches? Is that because some data are already in expect's buffers?

> You may find it helpful to use the -d flag when you run Expect to see
> what matches are being attempted.

Thanks. This explained me many things. So I have additional question :)

The documentation for expect recommends using "^...$" to get a match for
the whole line. As I can see (by -d flag), expect is trying to match a text
consisting of several lines to one pattern! Please look at the following
code:

proc get_devlist name {
set devlist {}

send "ls $name\r"

expect {
-re {-+ \|-+} {}
-re {=+ \|=+} {exp_continue}
-re ".*[string toupper $name](\[0-9\]+) *.*" {
#DEBUG
puts "Buffer-in-line: $expect_out(buffer)"; exp_continue
}
}

#DEBUG
puts "Buffer: $expect_out(buffer)"

foreach ln [split $expect_out(buffer) "\r"] {
#DEBUG
puts "Researching line: \[$ln\]"
set num {}
if { [regexp ".*[string toupper $name](\[0-9\]+).*" $ln rng num] } {
lappend devlist "$name$num"
}
}

puts $devlist
}

puts [get_devlist lks]
puts [get_devlist cks]

When I had "-----" and "=====" in the first expect statement, then I could
run get_devlist with lks or with cks and this worked correctly. However, when
get_devlist was called for cks just after calling for lks - the first worked,
the second did not.

I just want that expect:
- use one match for each line
- when a line matches pattern, execute a command and continues matching
- stop matching when appropriate pattern matches (it means: ignore rest
of the output read so far)

It is of course unusual that I read the data directly from $expect_out(buffer),
but so far it has been the only solution, which worked.

Don Libes

unread,
Aug 5, 2004, 2:24:12 PM8/5/04
to
Sektor van Skijlen <sek...@hasiok.org> writes:

> Don Libes <li...@nist.gov> wrote:
> > Sektor van Skijlen <etho...@wp.spamu.lubie.nie.pl> writes:
>
> > > Dnia 30 Jul 2004 13:33:37 -0400, Don Libes skrobie:
> > > > Sektor van Skijlen <sek...@hasiok.org> writes:
> > >
> So maybe you would be able to explain me, why expect "remembers" previous
> matches? Is that because some data are already in expect's buffers?

I don't understand this question.

> > You may find it helpful to use the -d flag when you run Expect to see
> > what matches are being attempted.
>
> Thanks. This explained me many things. So I have additional question :)
>
> The documentation for expect recommends using "^...$" to get a match for
> the whole line. As I can see (by -d flag), expect is trying to match a text
> consisting of several lines to one pattern! Please look at the following

Can you be more specific? I don't recall any documention that says
^...$ will match a whole line. If it does, it's defining a "line"
differently than I do.

> I just want that expect:
> - use one match for each line

To match a line, I generally use -re "\[^\r]*\r\n"

> - when a line matches pattern, execute a command and continues matching

Expect does that by default.

> - stop matching when appropriate pattern matches (it means: ignore rest
> of the output read so far)

Expect does that by default.

Don

0 new messages