Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

TCL(Tool Command Language) Scripting

Strange behavior when I tried to use expect -re {.*} to get the whole output from a command.


Hi all,

In my expect script, I tried to use:

expect -re {.*} ...

to get all the output of a command, but it didn't.

The following is the command I send:

insert into table1 values (1,'abcde');commit;

and the output is like:
SQL> insert into table1 values (1, 'abcde');
Transaction Done
SQL>

In my script, there's a place expecting the prompt "SQL>". But because
it appears in the output more than once, I have to use "expect -re
{.*}" to get the rest of the output. The problem is that it doesn't
seem to work.

My script is like:

expect {
    -re $lTargetPrompt {
        append lOutput $expect_out(buffer)
        expect -re {.*} {append lOutput $expect_out(buffer)}
    }
    ...

}

Does anyone have any ideas?

Thanks in advance!

Jack

On May 10, 6:03 am, zhjac@gmail.com wrote:

yes, the regexp {.*} matches 0 or more so it wont even look at the
expect buffer it just matches on ""
Also since you don't know what the expect buffer has at one time if
you dont provide anything to anchor
your regexp you can get different results every time you run your
program especially if you provide a
catch all that absorbs the expect_out(buffer) every time through the
loop. For instance ( see code below)
because of system load the initial expect buffer is "xxxxxSQL>" then
it will match and everything is fine and it never
reaches the catch all. Under heavy load the buffer may only be
"xxxxxSQ" your catch all will match and
on the next go round the "QL>" will not match either resulting in the
catch all running
expect {
         -re {(.*)SQL>} {
                       append output $expect_out(1,string)\n"
                       puts "FOUND MATCH $output"
                      }
         -re {.+} {
                       append output $expect_out(buffer);
                       puts "CATCHALL"

since your expression SQL> is never seen then it never matches.  A
better way is to do this:
expect {
      -re {(.*)SQL>$} {  # prompt are usually on line by itself
                   append output $expect_out(1,string) incr count
                   if  {  $count < $expectedNumPrompts } {
                        exp_continue;
                   }
            }
      -re {^.*$} { # match lines
                 lappend output $expect_out(buffer)
                }
      eof {
              ;
           }
     timeout {
              exp_continue ;
            }
 }

Carl

On May 10, 9:39 am, Bezoar <cwjo@gmail.com> wrote:

Sorry post was incorrect Google posted it before I could finish
editing it Correction below:
 yes, the regexp {.*} matches 0 or more so it wont even look at the
expect buffer it just matches on "" Also since you don't know what the
expect buffer has at one time if you dont provide anything to anchor
your regexp you can get different results every time you run your
program especially if you provide a catch all that absorbs the
expect_out(buffer) every time through the loop. For instance ( see
code below) because of system load the initial expect buffer is
"xxxxxSQL>" then it will match and everything is fine and it never
reaches the catch all. Under heavy load the buffer may only be
 "xxxxxSQ" your catch all will match and
 on the next go round the "QL>" will not match either resulting in the
 catch all running
 expect {
          -re {(.*)SQL>} {
                        append output "$expect_out(1,string)\n"
                        send_user "FOUND MATCH $output\r"
                       }
          -re {.+} {
                        append output $expect_out(buffer);
                        send_user "CATCHALL\n"
                        exp_continue;
                }
          }

results in first case:
 FOUND MATCH ...
in second case
 CATCHALL
 CATCHALL

   A better way is to do this:
#!/opt/usr/bin/tclsh8.5
package require Expect
spawn <program>
expect -re {.*SQL>} {
          send "<command>\r"

}

set output ""
exp_internal 0; # set to 1 for deep debugging
log_user 0 ; # set to 1 to see the program output
set count 0; # keep count of prompts
set expectedNumPrompts 1 ; # num prompts we want to see
# if we dont know the number prompts than another anchor
#(match expression) must be used or timeout/eof
expect {
    -re {(.*)SQL>} {
        append output $expect_out(1,string)
        send_user "."
        incr count
        if  {  $count < $expectedNumPrompts } {
            exp_continue;
        }
    }
    eof {
        send_user"+";
    }
    timeout {
        exp_continue ;
    }
}

puts "$output"

 Carl

In article <1178795034.155683.94@e65g2000hsc.googlegroups.com>,

                        .
                        .
                        .
There are several difficulties in the fragments you provide.  I
think <URL: http://wiki.tcl.tk/2958 >, <URL: http://wiki.tcl.tk/3173 >,
and <URL: http://wiki.tcl.tk/18013 > will interest you.

I don't understand your description.  You write
     ...
  and the output is like:
  SQL> insert into table1 values (1, 'abcde');
  Transaction Done
  SQL>

  In my script, there's a place expecting the prompt "SQL>". But because
  it appears in the output more than once, I have to use "expect -re
  {.*}" to get the rest of the output. The problem is that it doesn't
     ...
What I see is that, after the single command "insert into ...", there's
a single "SQL> " (that space might eventually be crucial, by the way)
prompt.  Are you saying that you're using Expect to script the launch
of an existing SQL script?

I suspect an experienced Expect programmer can solve your symptom in
seconds.  I write this to encourage you; it's very likely a solution is
near at hand.

I don't know in what kind of database environment you are trying to execute
your insert statement and why you use Expect. You will have valid reasons
for that, so only just to be sure:
You do realize that there are Tcl packages for accessing databases in a more
direct way?
E.g. Oratcl (http://wiki.tcl.tk/204) allows  you  to open a  connection to
an Oracle instance and execute queries like in your example without the need
to use Expect (and there's no hassling with the SQL> prompt)
Similar solutions exists for other databases as well
(http://wiki.tcl.tk/620)

Harm

<zhjac@gmail.com> wrote in message

news:1178795034.155683.94330@e65g2000hsc.googlegroups.com...

Hi Carl,

Thanks for your answer. But my problem is that I don't know how many
times the SQL> prompt will appear. That is because I'm providing some
Expect API to the end users, and the command is sent by the them.

What I want to do is just to collect all output from the command to a
variable.

I know that I can play a trick by setting a smaller timeout value and
a "gotprompt" flag, but I think it is ugly.

Jack

In article <1178854069.684014.77@o5g2000hsb.googlegroups.com>,

 <zhjac@gmail.com> wrote:
>Hi Carl,

>Thanks for your answer. But my problem is that I don't know how many
>times the SQL> prompt will appear. That is because I'm providing some
>Expect API to the end users, and the command is sent by the them.

>What I want to do is just to collect all output from the command to a
>variable.

>I know that I can play a trick by setting a smaller timeout value and
>a "gotprompt" flag, but I think it is ugly.

>Jack

There *must* be a better way.  What you describe sounds not only
ugly, but low in reliability.

It sounds as though the goal is to receive the results of SQL
queries.  There are *lots* of ways to do that, few of which
involve guessing timeouts.  Is there a way to focus your users'
attention on the queries rather than "some Expect API"?  It sure
seems to me that would lead to more satisfaction.

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc