測試環境為 CentOS 7 x86_64 虛擬機
Expect 可以預先編寫與 Linux shell 的終端視窗 (當前的行程 process) 所顯示的字串來產生相對應的動作.跟 TeraTerm 的 Macro 類似 – http://benjr.tw/20386
須先安裝 expect 套件.
[root@localhost ~]# yum install expect
直接來看一個範例:
當使用者輸入 Hi 或是 How are you 會回應相對應的字串,然後繼續執行,除非是輸入 Bye 才會返回 terminal,如果使用者鍵盤在10秒內沒有輸入任何值時也會返回 terminal (重置超時計時器 timeout 10 秒).
[root@localhost ~]# cat test.exp #!/usr/bin/expect set timeout 10 expect { "Hi" {send "Hi\n"; exp_continue} "How are you?" {send "Fine\n"; exp_continue} "Bye" {send "Bye Bye\n"; exit} }
參數說明:
- timeout – 如果使用者鍵盤或是其他程式執行沒有產生任何值,預設等待時間為 10秒即結束,可以使用 -1 代表沒有中斷時間.
- expect – 等待指定的 patterns 出現在 terminal (當前的行程 process) 上(使用者輸入或是其他程式執行時產生).
- send – 將字串發送到當 terminal (當前的行程 process) 上.
- exp_continue – 會繼續執行而不是返回 terminal (當前的行程 process),預設會重置超時計時器 timeout .
- exit – 退出 expect .
實際測試可以看到當使用者輸入 Hi 或是 How are you 會回應相對應的字串,然後繼續執行,最後輸入 Bye 才會返回 terminal.
[root@localhost ~]# chmod a+x test.exp [root@localhost ~]# ./test.exp Hi Hi How are you Fine Bye bye bye
自動登入 SSH
在 Linux 環境下使用 SSH 進行遠端連線,需要輸入密碼,除了可以透過把公鑰匯出 http://benjr.tw/301 或是透過指令 sshpass – http://benjr.tw/8287 ,另外一種方式就是透過 expect
下面範例使用 expect 透過遠端 ssh (免輸入密碼) 來執行指令.
[root@localhost ~]# vi ssh.exp #!/usr/bin/expect set timeout 10 set HOST [lindex $argv 0] set USER [lindex $argv 1] set PASS [lindex $argv 2] spawn ssh -o StrictHostKeyChecking=no $USER@$HOST expect { "password:" {send "$PASS\r"} } interact
參數說明:
- timeout – 如果使用者鍵盤或是其他程式執行沒有產生任何值,預設等待時間為 10秒即結束,可以使用 -1 代表沒有中斷時間.
- expect – 等待指定的 patterns 出現在 terminal (當前的行程 process) 上(使用者輸入或是其他程式執行時產生).
- send – 將字串發送到當 terminal (當前的行程 process) 上.
- $argv 0,1,2 – 執行 expect 後面所接的命令行參數.
- spawn – 產生新的行程 (process).
- interact – 把目前行程 (process)的控制權交還給使用者.
指令說明:
- ssh -o StrictHostKeyChecking=no $USER@$HOST
在 SSH Client 第一次登入時 SSH Server 會詢問是否接收公開金鑰 (SSH Client 需要輸入 yes),使用參數 StrictHostKeyChecking no 讓預設都為接受.
[root@localhost ~]# chmod a+x ssh.exp [root@localhost ~]# ./ssh.exp 192.168.95.205 root 111111 spawn ssh -o StrictHostKeyChecking=no root@192.168.95.205 root@192.168.95.205's password: Last login: Fri Jan 18 18:18:16 2019 from 192.168.95.205 [root@localhost ~]# exit logout Connection to 192.168.95.205 closed. [root@localhost ~]#
使用 autoexpect 來產生 exp 檔
還有一種方式可以更簡單完成,只需要透過 autoexpect 來記錄並產新相對應的 exp 檔.
自動登入 SSH 執行 hostname 後結束.
[root@localhost ~]# autoexpect -f autossh.exp ssh root@192.168.95.205 autoexpect started, file is autossh.exp root@192.168.95.205's password: Last login: Fri Jan 18 18:29:37 2019 from 192.168.95.205 [root@localhost ~]# hostname -a localhost.localdomain localhost4 localhost4.localdomain4 localhost.localdomain localhost6 localhost6.localdomain6 [root@localhost ~]# exit logout Connection to 192.168.95.205 closed. autoexpect done, file is autossh.exp
不過紀錄得太詳細了,可能還需要修改後才能使用.
set timeout -1 spawn ssh root@192.168.95.205 match_max 100000 expect -exact "root@192.168.95.205's password: " send -- "111111\r" expect -exact "\r Last login: Fri Jan 18 18:29:37 2019 from 192.168.95.205\r\r ^[\]0;root@localhost:~^G^[\[?1034h\[root@localhost ~\]# " send -- "hostname -a\r" expect -exact "hostname -a\r localhost.localdomain localhost4 localhost4.localdomain4 localhost.localdomain localhost6 localhost6.localdomain6\r ^[\]0;root@localhost:~^G\[root@localhost ~\]# " send -- "exit\r" expect eof
修改後的內容:
set timeout -1 spawn ssh root@192.168.95.205 match_max 100000 expect -exact "root@192.168.95.205's password: " send -- "111111\r" expect "#" send -- "hostname -a\r" expect "#" send -- "exit\r" expect eof
參數說明:
- timeout – 如果使用者鍵盤或是其他程式執行沒有產生任何值,預設等待時間為 10秒即結束,可以使用 -1 代表沒有中斷時間.
- spawn – 產生新的行程 (process).
- match_max – defines the size of the buffer (in bytes) used internally by expect.
- expect – 等待指定的 patterns 出現在 terminal (當前的行程 process) 上(使用者輸入或是其他程式執行時產生).
- send – 將字串發送到當 terminal (當前的行程 process) 上.
- eof – The corresponding body is executed upon end-of-file.
[root@localhost ~]# ./autossh.exp spawn ssh root@192.168.95.205 root@192.168.95.205's password: Last login: Fri Jan 18 19:06:33 2019 from 192.168.95.205 [root@localhost ~]# hostname -a localhost.localdomain localhost4 localhost4.localdomain4 localhost.localdomain localhost6 localhost6.localdomain6 [root@localhost ~]# exit logout Connection to 192.168.95.205 closed.
沒有解決問題,試試搜尋本站其他內容