首頁  >  文章  >  運維  >  實例講解expect指令實現Shell自動化交互

實例講解expect指令實現Shell自動化交互

小云云
小云云原創
2017-12-22 09:19:262819瀏覽

本文我們將實例講解expect指令實現Shell自動化交互,我們透過Shell可以實現簡單的控制流功能,如:循環、判斷等。以下這篇文章主要為大家介紹了關於利用expect指令實現Shell自動化互動的相關資料,文中透過範例程式碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。

背景

linux腳本中有很多場景是進行遠端操作的,例如遠端登入ssh、遠端複製scp、檔案傳輸sftp等。這些命令中都會涉及安全密碼的輸入,正常使用命令時是需要人工手動輸入密碼並接受安全驗證的。為了實現自動化遠端操作,我們可以藉用expect的功能。

expect是一個免費的程式設計工具語言,用來實現自動和互動式任務進行通信,而無需人的干預。 expect是不斷發展的,隨著時間的流逝,其功能越來越強大,已經成為系統管理員的一個強大助手。 expect需要Tcl程式語言的支持,要在系統上運行expect必須先安裝Tcl。

expect的安裝

expect是在Tcl基礎上創建起來的,所以在安裝expect前我們應該先安裝Tcl。

(一)Tcl 安裝

主頁: http://www.tcl.tk

下載位址: http://www.tcl .tk/software/tcltk/downloadnow84.tml

1.下載原始碼套件

wget http://nchc.dl.sourceforge.net/sourceforge/tcl/tcl8.4.11-src.tar.gz

2.解壓縮原始碼套件

tar xfvz tcl8.4.11-src.tar.gz

3.安裝設定

cd tcl8.4.11/unix 
./configure --prefix=/usr/tcl --enable-shared 
make 
make install

注意:

1、安裝完畢以後,進入tcl原始碼的根目錄,把子目錄unix下面的tclUnixPort.h copy到子目錄generic。

2、暫時不要刪除tcl原始碼,因為expect的安裝過程還需要用。

(二)expect 安裝(需Tcl的庫)

主頁: http://expect.nist.gov/

1.下載原始碼套件

wget http://sourceforge.net/projects/expect/files/Expect/5.45/expect5.45.tar.gz/download

2.解壓縮原始碼套件

tar xzvf expect5.45.tar.gz

3.安裝設定

cd expect5.45 
./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-tclinclude=../tcl8.4.11/generic 
make 
make install 
ln -s /usr/tcl/bin/expect /usr/expect/bin/expect

expect

expect的核心是spawn、expect 、send、set。

spawn 呼叫要執行的指令

  • expect 等待指令提示訊息的出現,也就是捕捉使用者輸入的提示:

  • send 傳送需要互動的值,取代了使用者手動輸入內容

  • #set 設定變數值

  • interact 執行完成後保持互動狀態,把控制權交給控制台,這個時候就可以手動操作了。如果沒有這一句登入完成後會退出,而不是留在遠端終端上。

  • expect eof 這個一定要加,與spawn對應表示捕獲終端輸出資訊終止,類似if....endif

expect腳本必須以interact或expect eof結束,執行自動化任務通常expect eof就夠了。

其他設定

  • 設定expect永不逾時set timeout -1

  • 設定expect 300秒逾時,如果超過300沒有expect內容出現,退出set timeout 300

#expect寫語法

expect使用的是tcl語法

  • 一條Tcl指令由空格分割的單字組成. 其中, 第一個單字是指令名稱, 其餘的是指令參數
    cmd arg arg arg

  • $符號代表變數的值. 在本例中, 變數名稱是foo.
    $foo

  • 方括號執行了一個巢狀指令. 例如,如果你想傳遞一個命令的結果作為另外一個命令的參數, 那麼你使用這個符號
    [cmd arg]

  • #雙引號把詞組標記為命令的一個參數. "$"符號和方括號在雙引號內仍被解釋
    "some stuff"

  • #大括號也把詞組標記為命令的一個參數. 但是, 其他符號在大括號內不被解釋
    {some stuff}

  • 反斜線符號是用來引用特殊符號. 例如:n 代表換行. 反斜線符號也被用來關閉"$"符號, 引號,方括號和大括號的特殊意義

#範例

login.exp專用於遠端登錄,快捷使用方式: login.exp "exclude" "${remote_ip}" "${remote_user}" "${remote_passwd}" "${remote_command}"

#!/usr/bin/expect -f
##########################################################
# 通过SSH登陆和执行命令
#参数:1.Use_Type [check/execute]
#  2.SSHServerIp
#  3.SSHUser
#  4.SSHPassword
#  5.CommandList [多个命令间以;间隔]
#返回值:
#  0 成功
#  1 参数个数不正确
#  2 SSH 服务器服务没有打开
#  3 SSH 用户密码不正确
#  4 连接SSH服务器超时
##########################################################
proc usage {} {
 regsub ".*/" $::argv0 "" name
 send_user "Usage:\n"
 send_user " $name Use_Type SSHServerIp SSHUser SSHPassword CommandList\n"
 exit 1
} 
## 判断参数个数
if {[llength $argv] != 5} {
 usage
}
#设置变量值
set Use_Type [lindex $argv 0]
set SSHServerIp [lindex $argv 1]
set SSHUser [lindex $argv 2]
set SSHPassword [lindex $argv 3]
set CommandList [lindex $argv 4]
#spawn ping ${SSHServerIp} -w 5
#expect {
# -nocase -re "100% packet loss" {
#  send_error "Ping ${SSHServerIp} is unreachable, Please check the IP address.\n"
#  exit 1
# }
#}
set timeout 360
set resssh 0
#定义变量标记ssh连接时是否输入yes确认
set inputYes 0
set ok_string LOGIN_SUCCESS
if {$Use_Type=="check"} {
 #激活ssh连接,如果要需要输入yes确认,输入yes,设置inputYes为1,否则输入ssh密码
 spawn ssh ${SSHUser}@${SSHServerIp} "echo $ok_string"
} else {   
 spawn ssh ${SSHUser}@${SSHServerIp} "$CommandList"
}
expect {
 -nocase -re "yes/no" {
  send -- "yes\n"
  set inputYes 1
 }
 -nocase -re "assword: " {
  send -- "${SSHPassword}\n"
  set resssh 1
 }
 #-nocase -re "Last login: " { 
 #  send -- "${CommandList}\n"
 #}
 $ok_string {}
 -nocase -re "Connection refused" {
  send_error "SSH services at ${SSHServerIp} is not active.\n"
  exit 2
 }
 timeout {
  send_error "Connect to SSH server ${SSHUser}@${SSHServerIp} timeout(10s).\n"
  exit 4
 }
}
#如果输入了yes确认,输入ssh密码
if {$inputYes==1} {
 expect {
  -nocase -re "assword: " {
   send -- "${SSHPassword}\n"
   set resssh 1
  }
 }
}
#如果出现try again或者password:提示,说明输入的用户密码错误,直接退出。
if {$resssh==1} {
 expect {
  -nocase -re "try again" {
   send_error "SSH user:${SSHUser} passwd error.\n"
   exit 3
  }
  -nocase -re "assword:" {
   send_error "SSH user:${SSHUser} passwd error.\n"
   exit 3
  }
  eof {}
 }
}
send_error -- "$expect_out(buffer)"
#-nocase -re "No such user" {
#  send_error "No such user.\n"
#  exit 5
# }
#exit

大家學會了嗎?希望學完本文之後大家對shell自動化互動有更深的掌握。

相關推薦:

Linux Shell製作錄製回放功能腳本

Python實作shell sed取代簡單的功能

Linux shell ftp按照日期去下載檔案的方法

以上是實例講解expect指令實現Shell自動化交互的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn