Question

I'm auto-interacting with an SSH session and an ERP program using Expect.

Rather than relying on a regular expression to capture a variable in my expect script would it be possible upon receiving a certain keystroke from a user to capture a screen region, say one field, into a variable in the code? Send the server some other commands and resend the field?

Say an order number is contained at 6, 12, 6, 18 (where 6 is the row and 12-18 are the columns) containing my 6 digit order number. I want to get that order number from row 6 columns 12 to 18 copy that into a variable. Then allow the user to interact some more (or expect a move into another menu), then re-send the order number in another menu.

So I guess my question is: Are the current screen's contents in one buffer? (not the whole session) Can you extract just a certain data element that would only exist at that row and column range on the screen?

Sample pseudocode:

#!/usr/bin/expect -f
set env(TERM) vt100
spawn ssh -Y user@domain
#... set user/pass and other vars...
#... send commands to log into ERP
#don't time out
set timeout -1 
        interact {
                -reset $CTRLZ {exec kill -STOP [pid]}
                $CTRLA   {   
                        exp_send "menu_address\ry\r"
                }
                $CTRLO   {   
                        #...acquire order number variable...
                        #...some code I don't understand yet...

                        exp_send "menu_exit_sequence\r"
                        exp_send "menu_address\r"
                        exp_send $ordernumvar

                }
                ~~
        }
Was it helpful?

Solution

No, you can't grab something off of the screen at a particular row/column. However, think about how the information got to the screen in the first place. If it's a tty-based application using curses it was output to stdout with special escape sequences that caused it to appear at that row/column. So, 'expect' those specific escape sequences to get what is at that position.

OTHER TIPS

Actually the term_expect example program that comes with Expect can do exactly this. It emulates a cursor-addressable terminal and allows you to test output at specific screen locations. In my ActiveTcl distribution it's in demos/Expect/term_expect.

To debug output of my ERP I found I could use exp_internal to get output characters.

exp_internal -f file 0

The output of that gave me: (my number entered being 076338)

spawn id exp0 sent <0>^M
spawn id exp6 sent <0>^M
spawn id exp0 sent <7>^M
spawn id exp6 sent <7>^M
spawn id exp0 sent <6>^M
spawn id exp6 sent <6>^M
spawn id exp0 sent <3>^M
spawn id exp6 sent <3>^M
spawn id exp0 sent <3>^M
spawn id exp6 sent <3>^M
spawn id exp0 sent <8>^M
spawn id exp6 sent <8>^M
spawn id exp0 sent <\r>^M
spawn id exp6 sent <\r\n\u001b[1;14H>^M

So now I need to figure out the regex to get the field. I had this:

-nobuffer -re {^([a-zA-Z0-9]{1})?[0-9]{5}$} {
    set ordernumber $interact_out(0,string)
}

but now I need to incorporate this:

^([a-zA-Z0-9]{1})?[0-9]{5}

With some regex that would represent this:

\r\n\u001b[1;14H

And then once I have that stored in the $ordernumber variable, I need to somehow isolate just the characters prior to the termination string and store those in a variable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top