Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 開發入門 >> Android教程之Expect網絡管理

Android教程之Expect網絡管理

日期:2016/3/13 17:12:49      編輯:開發入門

簡介: Expect 是進行高效的系統和網絡管理工作不可或缺的一種工具,不過很多人對它存在著一定的誤解。在本文中,將通過一些常見的用例來介紹 Expect 所提供的優點。

如果您從事系統和網絡管理工作,那麼您將需要 Expect。

更准確地說,您為什麼不使用 Expect 呢?對於一些常見的任務,它可以節省大量的時間。盡管您現在可能已經在使用 Expect,但是您可能並不是很清楚下面所描述的一些功能。

Expect 可以實現命令行交互的自動化

要從 Expect 中獲益,您並不需要掌握有關它的所有內容;讓我們從一個具體的示例開始,研究 Expect 如何在 AIX® 或者其他操作系統中簡化您的工作:

假設您在一些 UNIX® 或者類 UNIX 主機上具有登錄帳號,並且您需要更改這些帳號的密碼,但是並沒有使用網絡信息服務(Network Information Service,NIS)、輕量級目錄訪問協議(Lightweight Directory Access Protocol,LDAP)或者能夠在每台計算機上識別出您是相同的登錄用戶的一些其他機制對這些帳號進行同步。在大多數情況下,登錄到一台特定的主機,並運行合適的 passwd 命令並不會花費很長的時間,可能只需要一分鐘而已。但是因為無法將您的密碼編寫在腳本中,所以您必須 進行“手動”登錄,是這樣嗎?

其實並不是這樣的。事實上,標准 Expect 分發版(完整的分發版)中包括一種命令行工具(以及描述其使用的手冊頁面!),該工具恰好可以負責完成這項煩瑣的工作。passmass(請參見參考資料)是使用 Expect 編寫的一個簡短的腳本,它可以使得在二十台計算機上進行密碼更改的工作就像在一台計算機上進行密碼更改那樣簡單。不需要反復地輸入相同的密碼,您可以只啟動一次 passmass,並允許您的桌面計算機負責更新每個單獨的主機。您節省了大量時間並可以稍事休息,同時對於已經輸入過的內容,極大地降低了錯誤輸入的可能性。

Expect 的限制

這個 passmass 應用程序是一個非常優秀的模型,它說明了 Expect 的許多常規特性:

  • 這個工具值得我們去使用和研究:這個實用工具已經編寫完成,並且可以免費地下載,它易於安裝和使用,可以節省大量的時間和精力。
  • 從某種意義而言,它的作用是“無關緊要的”。如果任何操作都“按照既定的規則”進行(如果您使用了 NIS 或者一些其他的域身份驗證或單點登錄系統),或者可以通過編寫腳本進行登錄,那麼就不需要使用 passmass 了。但實際情況並不總是這樣的,而 Expect 非常適合於處理各種各樣現有的問題。也許 Expect 能夠幫助您節省更多的時間,以便您能夠使您的配置更加合理化,這樣一來您就不再需要 Expect 了。在此期間,您可以充分地利用它。
  • 對於分布式的環境,passmass 僅使用 telnetrlogin 或者 slogin進行登錄。我希望當前所有的 developerWorks 讀者都不再使用這些協議,而是使用 sshpassmasss 並沒有 對 ssh 提供全面的支持。
  • 另一方面,幾乎所有與 Expect 有關的內容都編寫得非常清楚,並且可以免費獲得。只需要使用三行簡單的內容(至多)就可以對passmass 進行增強,以支持 ssh 和其他選項。

您可能已經了解了足夠多的內容,完全可以開始編寫或者修改您自己的 Expect 工具。當然,實際上 passmass 分發版中包含了以 ssh方式進行登錄的代碼,但是省略了相應的命令行解析以到達這部分代碼。本文介紹了一種方法,您可以修改分發版源代碼,對 ssh 與telnet 以及其他協議進行同樣的處理:


清單 1. 經過修改的、接受 -ssh 參數的 passmass 片段

                    

            ...
         } "-rlogin" {
            set login "rlogin"
            continue
        } "-slogin" {
            set login "slogin"
            continue
        } "-ssh" {
            set login "ssh"
            continue
        } "-telnet" {
            set login "telnet"
            continue
           ...
      

 

在我自己的代碼中,我實際上從這個“樣本”中提出了更多的內容。現在,passmass 第 100 行附近的這一連串測試,非常好地說明了 Expect 的可讀性。這裡並沒有涉及到很深的編程技術,不需要面向對象、單體應用程序、協同例程,或者其他巧妙的技術。您只是請求計算機負責您通常進行的輸入工作。恰好,這個簡單的操作步驟可以節省大量時間和精力。

什麼是 Expect?

Expect 究竟 什麼,您應該如何使用它呢?

“Expect”涉及到一些獨特的概念,許多經常使用 Expect 的用戶對這些概念並不是十分清楚:

  • Expect 是一種特定的、高級的和通用的編程語言,其語法與 Tcl 相同,並增加了 Tcl 中所沒有的一些特殊用途的命令。
  • Expect 是一種可執行程序,從它正確地處理用 Expect 語言編寫的輸入的角度來看,它實現了這種語言。
  • expect 命令是其中的一個命令,Expect 以此對 Tcl 進行了擴展。
  • Expect 是一個 Tcl 包。一般說來,這意味著任何 Tcl 應用程序都可以在運行時加載 Expect 功能。
  • Expect 是一個基於 C 源代碼的庫,而這些 C 源代碼則深入到 Expect 可加載的包和 Expect 可執行程序。
  • Expect 是某種工具的抽象概念,該工具:
    • 實現終端交互的自動化,甚至在涉及到密碼或者其他特殊項目的情況下
    • 實現了一種“對話”模型,通過它對消息和響應的簡單規律進行編碼
    在這種抽象中,不存在特定於 Tcl 的內容,實際上,現在有幾種使用其他語言(如 Python、Perl,等等)的 Expect 模型的獨立實現。盡管本文中的示例都采用基於 Tcl 的 Expect 進行表述,但是可以使用其他語言來編寫所有這些示例。沒有理由因為您熟悉或者不熟悉 Tcl,而限制您對 Expect 的使用。

請注意,考慮到一些技術細節超出了本文的關注重點,在前面的描述中,我稍微有些歪曲事實;例如,常規的 Expect 可執行程序不僅擴展了 Tcl 命令集,它還可以識別啟動時的一些額外的命令行參數。盡管這些內容並不是專門針對主要的主題:一個簡短的 Expect 程序所能夠為系統管理員完成的工作,超出了大多數人的預期。

在了解了這個背景信息之後,“passmass 是一個 Expect 應用程序”表示:

  • passmass 是一個以 Expect 語言編寫的文本文件。
  • 如果您在正確地安裝了 Expect 和 passmass 的主機上執行 expect passmass ...,那麼您將得到正確的 passmass 功能。

請注意,具體的執行方法可能有一些變種:可以在一個 Tcl 解釋器中以交互的方式加載 Expect、運行 passmass、創建 passmass 作為一個獨立的可執行程序,等等。同樣地,這些替代方法超出了本文所關注的重點。

網絡管理示例

讓我們考慮一項更大的挑戰,網絡操作中心的日常操作中一項更典型的操作:檢索一組托管的 Cisco 交換機的當前配置信息。盡管有些站點使用 SNMP 或者 HTTP 來進行這些操作,但是更常見的是使用控制台或者頻內 telnet 會話來獲取該信息。許多管理員認為,完成這項工作唯一可行的方法是輸入與清單 2 中所示類似的命令。


清單 2. 典型的“手工”配置自檢

                    

        telnet $MY_ROUTER
        [User: admin]
        [passWord: ...]
        CCNA01# show running-config
        [... Current configuration:
         ... version 12.0 ...
         FIFTY LINES MORE OF CONFIGURATION DETAIL
         ...
         End]

    

 

其實並不是這樣的;實際上,通過在 cron、回復郵件(mailback)服務器,或者類似的作業控制機制(請參見清單 3)中進行調用,這項工作完全可以實現自動化。


清單 3. 配置自檢的自動化

                    
      #!/usr/bin/expect

      # initialize host, password, ...

      package require Expect
      set prompt {[00m# }
      spawn telnet $host
      expect {User: }
      send admin\r
      expect password:
      send $passWord\r
      expect -exact $prompt
      send "show running-config\r"
      expect -exact $prompt
      send exit\r
  

 

這個腳本可以自動地檢索路由器的配置信息,即在正確地編寫了腳本之後,對其進行監視時不再需要輸入密碼或者進行干預。

一些常見的混淆

這個示例是典型的 Expect 使用情況,其中有幾點值得注意。首先,不存在任何適用於各種情況的解決方案。許多管理員在獲得 Expect 時都認為它是一個單獨使用的工具,以解決他們當前所碰到的問題。那不是 Expect。Expect 與電子鐵釘尋找器 (electronic stud finder) 不同,後者可以不依靠任何其他工具、獨立地查找鐵釘。Expect 更像是一個手鑽:您必須將其與合適的鑽頭,或者轉換接頭、孔鋸,或者其他附件進行組合,才能真正實現它的用途。

同樣地,Expect 至少需要進行一些自定義工作。當然,我通常使用 Expect 來解決一些其他工具所無法輕松解決的問題。running-config 的案例說明了,只需要幾行內容,Expect 就可以自動地獲得大量的信息。即使是這個簡單的示例,也呈現出 Expect 所帶來的一些問題。例如,這種特定的自動化,需要將管理密碼以明文的形式嵌入到 Expect 腳本中;您需要判斷,它是否適合於您的具體環境。

這個案例至少在一些更多的方面是非常典型的。$prompt 讓我感到有些奇怪。屏幕上所顯示的是 CCNA01# ;對於許多設備來說,這是非常典型的,這個提示符實際上嵌入了一些不可見的控制字符。幸運的是,Expect 提供了各種有價值的調試開關,以報告其交互過程;這正是我確定 CCNA01 所生成的各種字符的方法。

另外,如前所述,清單 3 返回了整個會話,包括我所需要的配置報告,還加上登錄和退出作為其開始和結束。隱含在一般請求中的另一個有關 Expect 的常見誤解是“檢索一個命令的值”。Expect 並沒有提供這些語義。當您坐在鍵盤前並輸入一個命令時,您將它的操作認為是在下一個提示符之前所看到的相關顯示。對於網絡互連協議(如 telnet),在結果和提示符之間實際上並沒有什麼區別;您可以作為一個觀察者對這些內容的含義進行分析。

與這種網絡通信模型完全一致,Expect 並不直接區分結果和提示符。所有的 Expect 都稱為對話,即它通過 send 發送的字符序列,以及它所期望(expect)的內容。因此在實際中,我使用一個正則表達式解析來為我提供所需要的細節信息。Expect 的擴展正則表達式功能非常強大,並且很容易通過代碼確定格式。現在,讓我們重點關注通常無法通過腳本實現自動化的廣泛主題。

並發

請記住,Expect 是一種功能強大的、通用的語言。實際的 Expect 應用程序通常用於解析命令行參數、將結果顯示在分欄的表格中、從數據庫中檢索歷史數據、顯示圖形用戶界面 (GUI),以及更多的用途。所有這些都是常規的計算工作,本文中的示例並沒有展示這些方面的內容。文本的重點是正確地理解 Expect 獨特的價值。

使用與清單 3 中所示類似的解決方案,網絡管理員通常會考慮下一步的“水平方向的”增強:從大量類似的計算機檢索這類報告。Expect 提供了循環構造 foreachwhile 等等,從而使得這樣的工作變得更加簡單。

它也可能很快地變得無法接受。假設您負責上百台 LAN 主機,這是一個比較常見的情況。您使用一個 Expect 腳本自動地依次登錄到這些計算機,並檢索重要的數據。現在,您對該腳本稍微進行一下抽象,以便對整個集合進行遍歷。

問題是,運行所得到的腳本可能會花費很長的時間。它登錄到一台主機,請求結果,接收結果,注銷,然後轉向下一台主機,請求一個新的結果,等等。這個過程中的延遲使得人們希望能夠使用某種方法一次性地請求所有的結果,並按照結果到達的順序對其進行收集,導致這些結果不同順序的原因包括網絡滯後、不同的負載,以及其他延遲。

有一種方法可以實現這種操作。實際上,Expect 提供了一些非常好的功能來同時管理多個對話。本文提供了一個程序的示例,該程序多次進行登錄,在每個登錄上執行一些長時間運行的命令,然後根據結果到達的順序進行接收;對這個案例進行了整理,以便這些結果返回的順序與其啟動順序相反(請參見清單 4)。


清單 4. 並發檢索來自多個登錄的報告

                    
       #!/home/claird/local/ActiveTcl/bin/tclsh 
       
       package require Expect
       
       log_user 0
       
       # Initialize user, passphrase, ... here.
       
           # Sequentially login and issue time-consuming commands to all
           # hosts.
       for {set i 0; set delay 8} {$delay > 0} {incr i; incr delay -1} {
           spawn ssh $user@$host
           set sid($i) $spawn_id
           expect rsa':
           send $passphrase
           expect "Last login"
           expect -ex $prompt
           set active($sid($i)) $i
           send -i $sid($i) "echo `date`; sleep $delay; echo `date`; echo \
           '$delay done on $i.'\r"
       }
       
       while {[llength [array names active]]} {
           expect -i [array names active] -ex $prompt {
                puts "RECEIVED:  $::expect_out(buffer)"
                send -i $expect_out(spawn_id) exit\r
                expect -i $expect_out(spawn_id) eof
                unset active($expect_out(spawn_id))
           }
       }
  

 

當您運行這個腳本時,將看到與清單 5 所示類似的結果。


清單 5. 運行清單 4 所得到的結果

                    
       RECEIVED:  echo `date`; sleep 1; echo `date`; echo '1 done on 7.'
       Mon Apr 23 22:15:15 UTC 2007
       Mon Apr 23 22:15:16 UTC 2007
       1 done on 7.
       RECEIVED:  echo `date`; sleep 2; echo `date`; echo '2 done on 6.'
       Mon Apr 23 22:15:15 UTC 2007
       Mon Apr 23 22:15:17 UTC 2007
       2 done on 6.
       RECEIVED:  echo `date`; sleep 3; echo `date`; echo '3 done on 5.'
       Mon Apr 23 22:15:15 UTC 2007
       Mon Apr 23 22:15:18 UTC 2007
       3 done on 5.
          ...
       RECEIVED:  echo `date`; sleep 8; echo `date`; echo '8 done on 0.'
       Mon Apr 23 22:15:14 UTC 2007
       Mon Apr 23 22:15:22 UTC 2007
       8 done on 0.
     

 

在編程的層次上,請注意,所有這些登錄都是通過基於密碼的 ssh登錄到相同的主機,並使用相同的用戶和密碼憑據。在一個更實際的示例中,可以通過更多行的代碼來管理各個不同的主機,對每個主機使用不同的帳號和登錄協議。盡管對於那些對網絡管理員非常 價值的命令,sleep 是一個很好的模型;但是沒有理由先睡眠數秒鐘,然後再返回。

即使這個示例,也無法盡述 Expect 的所有功能。Expect 還提供了使用一個內置的套接字編程接口,直接管理 TCP/IP 對話的功能,並且它可以實現半自動化,在兩種不同的模式之間來回切換,用戶在其中一種模式中輸入部分對話,而 Expect 在另一種模式中實現所有操作的自動化。

我們將在以後的文章中介紹這些主題。本文的目標是,展示 Expect 中包含了大多數管理員並不知道的許多內容,具體來說是了解了該工具後,馬上就能夠解決網絡管理工作中各種常見的問題。在腳本中使用密碼和密碼條目,以及並發地控制多個連接,這些功能都是非常強大的。

總結

Expect 可以完成所有看起來無法實現自動化的工作:在腳本中使用密碼條目、登錄到遠程用戶的會話和返回對他或者她的控制,以及更多的工作。盡管它已經得到了廣泛使用,但是 Expect 卻常常被人們所誤解。正確地理解有關 Expect 的一些基本知識(如何調用它、它的對話模型、它的編程輔助,等等),以便在系統和網絡管理工作中更充分地發揮它的作用。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved