expect簡介和使用例子


expect簡介

expect是一款自動化的腳本解釋型的工具。

expect基於tcl腳本,expect腳本的運行需要tcl的支持。

expect對一些需要交互輸入的命令很有幫助,比如ssh ftp scp telnet。

遠程登錄linux服務器的時候,ssh命令需要手工輸入密碼,當登錄多台機器的時候就會非常繁瑣。

expect就可以根據設定的規則,自動幫我們輸入密碼,大大節省了時間。

expect安裝

一般機器不會自帶expect,需要手動安裝。

系統為RHEL/CentOS:

yum install expect

系統為Debian/Ubuntu:

apt-get install expect

expect基礎知識

expect腳本

腳本開頭

expect腳本一般以#!/usr/bin/expect -f開頭,類似bash腳本。

常用后綴

expect腳本常常以.exp或者.ex結束。

expect主要命令

  • spawn 新建一個進程,這個進程的交互由expect控制
  • expect 等待接受進程返回的字符串,直到超時時間,根據規則決定下一步操作
  • send 發送字符串給expect控制的進程
  • set 設定變量為某個值
  • exp_continue 重新執行expect命令分支
  • [lindex $argv 0] 獲取expect腳本的第1個參數
  • [lindex $argv 1] 獲取expect腳本的第2個參數
  • set timeout -1 設置超時方式為永遠等待
  • set timeout 30 設置超時時間為30秒
  • interact 將腳本的控制權交給用戶,用戶可繼續輸入命令
  • expect eof 等待spawn進程結束后退出信號eof

expect命令分支

expect命令采用了tcl的模式-動作語法,此語法有以下幾種模式:

單一分支語法

set password 123456
expect "*assword:" { send "$password\r" }

當輸出中匹配*assword:時,輸出password變量的數值和回車。

多分支模式語法

set password 123456
expect {
      "(yes/no)?" { send "yes\r"; exp_continue }
      "*assword:" { send "$password\r" }
}

當輸出中包含(yes/no)?時,輸出yes和回車,同時重新執行此多分支語句。

當輸出中匹配*assword:時,輸出password變量的數值和回車。

expect詳細講解

ssh遠程登錄expect腳本

下面是一個自動登錄系統hostname1和hostname2執行uname -a后斷開連接的腳本。

先建立login.exp

touch login.exp
chmod +x login.exp
vim login.exp

內容如下:

#!/usr/bin/expect -f

set timeout -1  //永遠等待,不會超時
spawn ssh root@hostname1   //spawn 后面跟命令名稱和參數

//如果匹配到*assword,那么發送密碼,並進入下面的expect語句(uname -a語句)。
//如果匹配到yes/no,那么發送yes,並重新執行這個expect語句。

expect {
    "*assword" {send "123456\r";}
    "yes/no" {send "yes\r";exp_continue}
}

//匹配到*]#,那么運行uname -a命令
expect "*]#" {send "uname -a\r"}

send "exit\r" //退出遠程登錄

expect eof //結束spawn

//開始下一個命令
spawn ssh root@hostname2
expect {
    "*assword" {send "123456\r";}
    "yes/no" {send "yes\r";exp_continue}
}
expect "*]#" {send "uname -a\r"}
send "exit\r" //退出遠程登錄
expect eof //結束spawn

exit //退出expect腳本

ssh遠程登錄shell腳本(嵌套expect)

shell中使用expect -c "expect腳本內容"來完成嵌套。

注意:

expect腳本里面的"都需要在前面加上轉義符號\。

每個expect語句后面加上分號";"。

vim expect_in_shell.sh

#!/usr/bin/bash

HOSTS="hostname1 hostname2"  
  
for host in $HOSTS  
do  
        expect -c "  
            set timeout 5;  
            spawn ssh root@${host};  
            expect {                
                \"*assword\" { send \"123456\r\" }  
 				\"yes/no\" { send \"yes\r\"; exp_continue }  
             } ;  
            expect \"*]#\"   {send \"uname -a\r\" }  ;  
		    send \"exit\r\" //退出遠程登錄
		    expect eof 
        "  
done  

帶參數的expect腳本ssh登錄

vim login_arg.exp

#!/usr/bin/expect -f
set ip [lindex $argv 0]   //第一個參數賦值給變量ip
set password [lindex $argv 1]  //第二個參數復制給變量password
set timeout -1
spawn ssh root@$ip
expect {
    "password" {send "$password\r";}
    "yes/no" {send "yes\r";exp_continue}
}
interact //停留在遠程shell

帶參數運行login_arg.exp

chmod +x login_arg.exp
./login_arg.exp 127.0.0.1 123456


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM