Shell編程之Expect免交互
Expect概述
Expect安裝
Expect基本命令
Expect執行方式
Expect案例
Expect概述
Expect
Expect
是創建在tcl
基礎上的一個工具,Expect
是用來進行自動化控制和測試的工具。主要解決shell
腳本中不可交互的問題。對於大規模的linux
運維頗有幫助
- 在
linux
運維和開發中,咱們常常須要遠程登陸服務器進行操做,登陸的過程是一個交互的過程,可能會須要輸入yes/no password
等信息。爲了模擬這種輸入,可使用Expect
腳本
Expect安裝
掛載光盤
製做本地YUM源
執行安裝命令
[root@localhost ~]# yum install expect -y
已加載插件:fastestmirror, langpacks
base | 3.6 kB 00:00:00
extras | 2.9 kB 00:00:00
updates | 2.9 kB 00:00:00
(1/4): extras/7/x86_64/primary_db | 152 kB 00:00:00
(2/4): base/7/x86_64/group_gz | 165 kB 00:00:00
(3/4): updates/7/x86_64/primary_db | 1.9 MB 00:00:01
...//省略部份內容...
正在安裝 : 1:tcl-8.5.13-8.el7.x86_64 1/2
正在安裝 : expect-5.45-14.el7_1.x86_64 2/2
驗證中 : 1:tcl-8.5.13-8.el7.x86_64 1/2
驗證中 : expect-5.45-14.el7_1.x86_64 2/2
已安裝:
expect.x86_64 0:5.45-14.el7_1
做爲依賴被安裝:
tcl.x86_64 1:8.5.13-8.el7
完畢!
Expect基本命令
send:向進程發送字符串,用於模擬用戶的輸入
expect
expect
的一個內部命令,判斷上次輸出結果裏是否包含指定的字符串,若是有則當即返回,不然就等待超時時間後返回。
- 只能捕捉由
spawn
啓動的進程的輸出
spawn:啓動進程,並跟蹤後續交互信息
interact:執行完成後保持交互狀態,把控制權交給控制檯
Timeout:指定超時時間,過時則繼續執行後續指令
- 單位是:秒
timeout -1
爲永不超時
- 默認狀況下,
timeout
是10
秒
exp_ continue
send_ user
$argv參數數組
Expect
腳本能夠接受從bash
傳遞的參數.可使用[lindex $argv n]
得到,n
從0
開始,分別表示第一個,第二個,第三個...參數
Expect腳本必須以interact或expect eof結束,執行自動化任務一般expect eof就夠了
expect eof
是在等待結束標誌。由spawn
啓動的命令 在結束時會產生一個eof
標記,expect eof
御在等待這個標記
Expect語法
單一分支語法
expect "password:" {send "mypassword\r";}
多分支模式語法
expect "aaa" {send"AAA\r"} //send命令不具有回車換行功能,通常要加\r或\n
expect "aaa" {send"AAA\r"}
expect "aaa" {send"AAA\r"}
expect {
"aaa" {send "AAA\r"} //只要配置aaa或bbb或ccc中的任何一個,執行相應的send語句後退出該expect語句
"bbb" {send "BBB\r"}
"ccc" {send "CCC\r"}
}
expect {
"aaa" {send "AAA";exp_continue} //exp_continue表示繼續後面的匹配,若是匹配了aaa,執行
"bbb" {send "BBB";exp_continue} 完send語句後還要繼續向下匹配bbb
"ccc" {send "CCC"}
}
Expect執行方式
直接執行
- 使用
expect
免交互使用ssh
遠程登陸另外一臺服務器,這裏我開啓兩臺Linux
服務器。
[root@localhost ~]# vim demo19.sh //編輯腳本文件
#!/usr/bin/expect //expect二進制文件路徑
set timeout 5 //超時時間
log_file tast.log //記錄日誌文件存放位置
log_user 1 //一個用戶
set hostname [lindex $argv 0] //設定第一個位置參數傳遞並設置變量名hostname
set password [lindex $argv 1] //設定第二個位置參數傳遞並設置變量名password
spawn ssh root@$hostname //追蹤命令
expect { //使用expect命令捕捉條件,設定輸入信息,進行免交互設置
"(yes/no)" //設定匹配條件
{send "yes\r";exp_continue} //條件匹配並輸入內容,並繼續向下匹配
"*password" //設定匹配條件
{send "$password\r"} //條件匹配,引用位置變量輸入信息
}
interact //完成後將控制權交給控制檯
[root@localhost ~]# chmod +x demo19.sh //給腳本文件添加執行權限
[root@localhost ~]# ./demo19.sh 192.168.144.135 123123 //執行腳本
spawn ssh root@192.168.144.135
The authenticity of host '192.168.144.135 (192.168.144.135)' can't be established.
ECDSA key fingerprint is SHA256:B8IsZOFG7FbtVkIK+dMILmo0iA4OEIeVGY0GnnCbXhk.
ECDSA key fingerprint is MD5:c2:d8:09:17:de:6e:ec:07:06:1b:ac:b6:1e:bd:62:09.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.144.135' (ECDSA) to the list of known hosts.
root@192.168.144.135's password:
Last login: Sun Oct 13 23:29:38 2019 from 192.168.144.1 //自動登陸服務器
[root@localhost ~]# ifconfig //查看服務器IP地址
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.144.135 netmask 255.255.255.0 broadcast 192.168.144.255 //成功登陸
inet6 fe80::a85a:c203:e2e:3f3c prefixlen 64 scopeid 0x20<link>
inet6 fe80::ad78:663f:1f02:22e4 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:75:9f:c8 txqueuelen 1000 (Ethernet)
...//省略部份內容...
嵌入執行
[root@localhost ~]# vim demo20.sh //編輯腳本文件
#!/bin/bash
hostname=$1 //設置位置參數變量
password=$2
/usr/bin/expect <<-EOF //加載expect功能,EOF前面加「-」是爲增長容錯性,-EOF 前面的「-"只能容錯製表
spawn ssh root@$hostname 符,不能容錯空格
expect {
"(yes/no)"
{send "yes\r";exp_continue} //進行免交互配置
"*password"
{send "$password\r"}
}
expect "*]#" //捕捉內容結尾爲「]#」的內容
send "exit\r" //匹配後輸入exit退出登陸
expect eof //等待結束標誌
EOF //結束標誌
[root@localhost ~]# chmod +x demo20.sh //添加執行權限
[root@localhost ~]# ./demo20.sh 192.168.144.135 123123 //執行腳本,並輸入位置變量
spawn ssh root@192.168.144.135
root@192.168.144.135's password:
Last login: Sun Oct 13 23:58:05 2019 from 192.168.144.1
[root@localhost ~]# exit
登出
Connection to 192.168.144.135 closed.
[root@localhost ~]# ifconfig //查看IP地址信息
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.144.133 netmask 255.255.255.0 broadcast 192.168.144.255
inet6 fe80::a85a:c203:e2e:3f3c prefixlen 64 scopeid 0x20<link> //成功登出
ether 00:0c:29:5b:d3:a0 txqueuelen 1000 (Ethernet)
RX packets 11058 bytes 855440 (835.3 KiB)
...//省略部份內容...