亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1367 | 回復(fù): 0
打印 上一主題 下一主題

關(guān)于在Linux/Unix環(huán)境下的Terminal終端自動交互 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2009-09-10 13:57 |只看該作者 |倒序瀏覽

               
               
                如何利用Expect來和Terminal自動交互
在Linux/Unix的世界里,用expect就可以很容易得就可以實現(xiàn)人機(jī)交互的功能,尤其網(wǎng)上好多examples實現(xiàn)比如password, ftp, telnet之類的程序都很簡單。但是如何很好的實現(xiàn)和終端程序交互,尤其是這個終端是用ncurses/curses實現(xiàn),有著豐富的顏色和復(fù)雜的結(jié)構(gòu),這樣的現(xiàn)有的expect就有點力不從心了。現(xiàn)在,筆者參與一個OpenSolaris的項目測試,這個測試要求能夠自動和終端交互,來實現(xiàn)復(fù)雜的自動人機(jī)交互的功能。但是這個項目使用ncurses + python bridge寫成的。為了追求好的用戶體驗,開發(fā)人員使用了很多的屏幕刷新,這就要求expect能購追蹤每一次刷新并且從用戶的最終角度來得到屏幕顯示的是什么。
比如:原來屏幕上顯示的是"Yes or no....", 但是在下一屏刷新的時候,可能之改變了幾個字符,顯示就變成了"Yesterday", 如下所示:
Y e s   o r   n o ...
Y e s t e r d a y ...
但是在expect_out(buffer)里面,顯示的就是"...Yes or no\r\n...^[[3Gterday", 這樣如果搜尋"Yesterday"這串字符就顯然不可能能夠搜到的。
有人會問"^[[3G"是什么?這個就是termcap/terminfo 用來使terminal具有豐富顯示功能的約定俗成方法。為了方便使用這些功能,人們就把他們組成了各種方法,封裝在curses/ncurses庫中。具體約定的方法請參見附錄1
在expect的創(chuàng)始人Don.Libes的論文〔附錄2〕中, 他提出了一種方法能夠解決上述terminal問題的自動人機(jī)交互,而且作為expect的FAQ給出。但是,他實現(xiàn)的方法是用tcl/tk來模擬一個后臺終端(tk terminal),把顯示的內(nèi)容用控制的方法來實現(xiàn)前臺終端和后臺終端同步顯示,在他封裝的腳本里,用term_expect〔附錄3〕來對后端terminal進(jìn)行監(jiān)控從而間接的對用戶程序顯示的前臺進(jìn)行監(jiān)控。
但是他的方法里面有一個限制,就是前端運行的terminal程序必須能在后端的tk Terminal上正常顯示,但是,據(jù)我所知,不同的terminal控制轉(zhuǎn)義字符是不一樣的,而tk terminal的轉(zhuǎn)移字符遠(yuǎn)遠(yuǎn)不能夠覆蓋所有其他的terminal類型,比如xterm. 而且有很多程序只能在諸如xterm這樣的終端上才能夠正常運行。這就造成了他給出的程序在實際應(yīng)用中受限。更何況很多情況下根本就不允許tk存在(在沒有X的情況下)。
Don.Libes 的例子中也給出了virterm〔附錄4〕作為非tk terminal的解決方案。但這同樣有問題,首先這個程序本身就是一個學(xué)生寫的,用于從他所在大學(xué)的圖書館里自動檢索,而且他模擬的后臺終端是tt終端現(xiàn)以不多見。所以在把virterm直接用于本例也不能夠?qū)崿F(xiàn)。
但是這里的核心思想?yún)s很有用,在后端模仿一個terminal的buffer,來把有用的東西寫到buffer里面。尋找一個定位符(cursor),根據(jù)expect_out(buffer)的內(nèi)容不斷的調(diào)整cursor的位置,不斷進(jìn)行刷新。這樣在buffer里面就能夠保證和前端terminal顯示一致。
首先要根據(jù)控制序列的所在終端調(diào)整完全轉(zhuǎn)義序列的內(nèi)容,使之在expect_out(buffer)一個個的得到處理,重點是根據(jù)內(nèi)容來調(diào)整cursor.在我的prototype的實驗中,如下內(nèi)容可以用于xterm.
expect {
    -re "^\r" {
        # (cr,) Go to to beginning of line
        set cur_col 0
        term_cursor_changed   
    } "^\n" {
        # (ind,do) Move cursor down one line
        term_down
        term_cursor_changed
    } "^\b" {
        # Backspace nondestructively
        incr cur_col -1
        term_cursor_changed
    } "^\a" {
        # Bell, pass back to user
        send_user "\a"
    } "^\t" {
        # Tab, shouldn't happen
        send_error "got a tab!?"
    } eof {
        term_exit
    } "^\x1b\\\[K" {
        # (ind,do) Move cursor down one line
        term_down
        term_cursor_changed
    } "^\x1b=" {
        #???
    } "^\x1b(B" {
        #
    } "^\x1b(0" {
        #
    } "^\x1b\\\[A" {
        # (cuu1,up) Move cursor up one line
        incr cur_row -1
        term_cursor_changed
    } "^\x1b\\\[C" {
        # (cuf1,nd) Nondestructive space
        incr cur_col
        term_cursor_changed
    } -re "^\x1b\\\[((\[0-9]{1,})(;*)(\[0-9]{1,}))*r" {
        set cur_row [expr $expect_out(2,string)+1]
        set cur_col $expect_out(4,string)
        term_cursor_changed        
    } -re "^\x1b\\\[(\[0-9]{1,2})*G" {
        # (cuu1,up) Move cursor to the line
        set cur_col $expect_out(0,string)
        term_cursor_changed
    } -re "^\x1b\\\[(\[0-9]{1,2})*m" {  # unsupported
    } -re "^\x1b\\\[((\[0-9]{1,2})(;*)(\[0-9]{1,2}))*m" {  # unsupported
    } -re "^\x1b\\\[((\[0-9]{1,2})(;*)(\[0-9]{1,2})(;*)(\[0-9]{1,2}))*m" {  # unsupported
        # (rmso,se) End standout mode
        set term_standout 0
    } -re "^\x1b\\\[(\[0-9]{1,})*X" {
    } -re "^\x1b\\\[(\[0-9]{1,})*H" {
        # (cuu1,up) Move cursor to the line
        set cur_row $expect_out(0,string)
        term_cursor_changed
    } -re "^\x1b\\\[((\[0-9]*);(\[0-9]*))*H" {
        # (cup,cm) Move to row y col x
        set cur_row [expr $expect_out(2,string)+1]
        set cur_col $expect_out(3,string)
        term_cursor_changed
    } -re "^\x1b\\\[(\[0-9]*)*l" {
    } -re "^\x1b\\\[(\[0-9]*)*J" {
        # (clear,cl) Clear screen
        term_init
        term_cursor_changed
    } -re "^\x1b\\\[\\\?(\[0-9]{1,})*h" {
        # (smkx,ks) start keyboard-transmit mode
         # terminfo invokes these when going in/out of graphics mode
        set cur_row 1
        term_cursor_changed
    } -re "^\x1b\\\[\\\?(\[0-9]{1,})*l" {
    } -re "^\[\x20-\x7e]+" {
        term_insert $expect_out(0,string)
        term_cursor_changed
    }
   在項目的具體實現(xiàn)過程中,由于匹配效率的問題,上述方法被另外以 C庫來寫成。首先我們用expect調(diào)取程序來實現(xiàn)終端交互,并且把expect_out(buffer)的內(nèi)容輸出供C程序來調(diào)取進(jìn)行實施分析。后端的buffer由C程序來進(jìn)行實現(xiàn)。然后expect在根據(jù)這個buffer里面的內(nèi)容能夠來對前端程序進(jìn)行匹配和其他操作。
   整體的結(jié)構(gòu)圖如下:
  

附錄:1. 控制終端代碼 - Linux 控制終端轉(zhuǎn)義和控制序列 http://www.chinalinuxpub.com/bbs/showthread.php?t=45194
2. Automation and Testing of Character-Graphic Programs
3. term_expect: http://expect.nist.gov/example/term_expect
4. virterm: http://expect.nist.gov/example/virterm
               
               
               
               
               
               
               
               
               

本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u/412/showart_2049636.html
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP