Linux 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章