2010-01-01 29 views
3

我使用Expect自動與SSH會話和ERP程序進行交互。期望 - 根據行和列獲取屏幕區域的變量

而不是依靠一個正則表達式來捕獲我期望的腳本中的一個變量,當從用戶接收到一個特定的按鍵來捕獲一個屏幕區域,比如說一個字段,在代碼中變成一個變量時,可能會這樣嗎?向服務器發送一些其他命令並重新發送字段?

假定訂單號包含6,12,6,18(其中6是行,12-18是列),其中包含我的6位數字訂單號。我想從第6行第12到18行將該訂單號複製到變量中。然後允許用戶進行更多交互(或期望進入另一個菜單),然後在另一個菜單中重新發送訂單號碼。

所以我想我的問題是:當前屏幕的內容在一個緩衝區? (而不是整個會話)您是否可以提取只存在於屏幕上該行和列範圍內的某個數據元素?

樣品僞代碼:

#!/usr/bin/expect -f 
set env(TERM) vt100 
spawn ssh -Y [email protected] 
#... 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 

       } 
       ~~ 
     } 

回答

0

不,你不能在一個特定的行/列搶東西離開屏幕。但是,想想信息如何到達屏幕上。如果它是一個使用curses的基於tty的應用程序,它將輸出到帶有特殊轉義序列的stdout,從而導致它出現在該行/列。所以,'期待'那些特定的逃避序列來獲得那個位置上的東西。

+0

什麼是這些特殊轉義序列之一的例子?我對基於tty的應用程序如何正確顯示有點陌生。另外,如果我的領域已經在屏幕上,並且只有在用戶觸發他們的操作以複製變量之後,我該如何「期待」我的領域?我猜這不可能預先確定該菜單的有用數據元素,並將它們預加載到變量中以供以後使用。例如, – jjclarkson 2010-01-01 15:19:00

+0

[1; 3H將光標移動到第1行第3列。我不確定在運行預期腳本之前它已經在屏幕上如何顯示。您的腳本是否需要登錄或啓動其他程序才能顯示初始屏幕? – 2010-01-01 17:02:13

+0

有趣......對於我正在處理腳本的場景,會產生一個SSH會話(根據shell設置,ERP程序會在登錄時自動啓動,儘管登錄序列也由腳本自動完成),然後雙手控制用戶使用「交互」,但某些按鍵(如Ctrl + o(以及其他許多按鍵))會觸發某些自動過程,然後手動控制返回給用戶。光標控制不是必需的,只需要選擇某些字段併發送某些命令。 – jjclarkson 2010-01-01 18:24:58

0

要調試我ERP的輸出,我發現我可以使用exp_internal來獲取輸出字符。

exp_internal -f file 0 

,它的輸出給了我(我的電話號碼輸入爲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 

所以現在我需要弄清楚的正則表達式來獲取字段。我有這樣的:

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

,但現在我需要把這樣的:

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

對於一些正則表達式這將是這樣的:

\r\n\u001b[1;14H 

,然後一旦我有一個存儲在$ ordernumber變量,我需要以某種方式隔離終止字符串之前的字符並將它們存儲在變量中。

+0

我嘗試{^([a-zA-Z0-9] {1})?[0-9] {5} \ r \ n \ u001b [1; 14H $}但出現錯誤我嘗試在其中投擲一些反斜槓那裏,但我只是猜測正確的正則表達式語法... – jjclarkson 2010-01-04 19:57:42

1

其實term_expect Expect附帶的示例程序可以完成此操作。它模擬一個光標可尋址的終端,並允許您在特定的屏幕位置測試輸出。在我的ActiveTcl發行版中,它是演示/ Expect/term_expect。