Expect自動化交互程序應用實踐
1.Expect簡介
1.1什麼是Expect
Expect是一個用來實現自動化交互功能的軟件套件,是基於TCL的腳本編程工具語言,方便學習,功能強大。
1.2爲什麼要使用Expect
在現在的企業運維中,自動化運維已經成爲運維的主流趨勢,但是在很多情況下,執行系統命令或程序時,系統需要以交互式的形式要求運維人員輸入指定的字符串,之後才能繼續執行命令。例如,爲用戶設置密碼時,一般情況下需要手工輸入2次密碼。ssh遠程連接服務器時需要輸入yes和密碼信息,才能連接。
expect自動化交互工作流程簡單說明,以此執行如下操作:
spawn 啓動指定進程------>expect獲取期待的關鍵字--->send向指定進程發送指定字符---->進程執行完畢,退出結束。
2.Expect安裝
rpm -qa expect查看機器是否已安裝。
yum -y install expect
3.小試牛刀:實現expect自動化功能
此次準備的是3臺虛擬機,IP和主機名如下
IP地址 主機名
192.168.132.20 salt-master
192.168.132.11 salt-minion01
192.168.132.10 salt-minion02
expect腳本如下:
[root@salt-master tmp]# cat tuwei.exp
#!/usr/bin/env expect ------解析器,使用expect解析
spawn ssh [email protected] uptime---執行ssh命令
expect {
"yes/no" {send "yes\r";exp_continue}
"*password" {send "x9i86wrz\r"}
send "x9i86wrz\n"
}
expect eof
執行時使用expect tuwei.exp
結果如下:
[root@salt-master tmp]# expect tuwei.exp
spawn ssh [email protected] uptime
The authenticity of host '192.168.132.11 (192.168.132.11)' can't be established.
RSA key fingerprint is 14:7f:3a:76:0b:db:11:eb:03:62:9e:0f:f8:b8:e4:45.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.132.11' (RSA) to the list of known hosts.
[email protected]'s password:
21:25:26 up 1:07, 1 user, load average: 0.00, 0.00, 0.00
4.expect常用命令
spawn:通過spawn命令執行一個命令或者程序,之後所有的expect操作都會在這個執行過的命令或程序中進行,包括自動交互功能。
spawn 選項 命令或程序
如 spawn ssh [email protected] uptime
expect:獲取spawn命令執行後的信息,看是否和事先定義的相匹配,一旦匹配就執行後面的動作。如:
expect "*password" {send "123456\r"}或者放在不同行
expect "*password"
send "123456\r"
send:expect匹配指定的字符串後,發送指定字符串給系統。
exp_continue:表示讓程序繼續匹配(用於多次匹配字符串並執行不同的動作)
send_user:打印expect腳本信息,類似shell裏的echo命令,而且有echo -e的功能。
exit:退出腳本,還可以利用該命令對腳本做一些關閉前的清理和提示等工作。
如
exit -onexit {
send_user "Good bye.\n"
}
5.變量
5.1普通變量
基礎語法如下:
set 變量名 變量值
如 set password "123456"
打印變量的基礎語法:
puts $變量名
5.2特殊參數變量
類似與shell中的$0,$1,$2,用於接收及控制expect腳本傳參。
$argv 表示參數數組
[lindex $argv n]接收expect腳本傳參,n從0開始。
如set file [lindex $argv 0]
set host [lindex $argv 1]
$argc表示傳參的個數,$argv0 表示腳本的名字。
6.if條件語句
基礎語法爲:
if {條件表達式} {
指令
}
或
if {條件表達式} {
指令
} else
{
指令
}
例如:
if {$argc != 2} {
send_user "usage:expect $argv0 file host"
exit
}
7.Expect中的關鍵字
關鍵字用於匹配過程,一般用於expect命令中。
eof(end of file)用於匹配結束符
timeout:控制時間的關鍵字變量。可以通過爲該變量賦值來規定整個expect操作的時間,服務於expect全局的。
set timeout 30 -----設置30s超時
8.企業生產場景expect案例
此次準備的是3臺虛擬機,IP和主機名如下
IP地址 主機名
192.168.132.20 salt-master
192.168.132.11 salt-minion01
192.168.132.10 salt-minion02
8.1批量執行命令
expect自動交互腳本test.exp
#!/usr/bin/env expect
if { $argc != 2 } {
send_user "usage:expect $argv0 ip command"
exit
}
set host [lindex $argv 0]
set cmd [lindex $argv 1]
set password "x9i86wrz"
spawn ssh root@$host $cmd
expect {
"yes/no" {send "yes\r";exp_continue}
"*password" {send "$password\r"}
}
expect eof
shell循環執行expect腳本 test.sh
#!/bin/sh
if [ $# -ne 1 ];then
echo "usage:$0 cmd"
exit 1
fi
cmd=$1
cat /tmp/iplist |while read ip
do
expect test.exp $ip "$cmd"
done
查看系統磁盤使用情況 sh test.sh "df -h"
[root@salt-master tmp]# sh test.sh "df -h"
spawn ssh [email protected] df -h
[email protected]'s password:
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 48G 4.0G 41G 9% /
tmpfs 285M 12K 285M 1% /dev/shm
/dev/sda1 194M 29M 155M 16% /boot
spawn ssh [email protected] df -h
[email protected]'s password:
Filesystem Size Used Avail Use% Mounted on
/dev/sda5 16G 4.7G 10G 33% /
tmpfs 334M 12K 334M 1% /dev/shm
/dev/sda1 190M 54M 127M 30% /boot
/dev/sda2 2.0G 3.2M 1.9G 1% /home
8.2批量發送文件
expect自動交互腳本fenfa.exp
#!/usr/bin/env expect
if { $argc != 3 } {
send_user "usage:expect $argv0 file ip dir"
exit
}
set file [lindex $argv 0]
set host [lindex $argv 1]
set dir [lindex $argv 2]
set password "x9i86wrz"
spawn scp -P22 -r -p $file root@$host:$dir
expect {
"yes/no" {send "yes\r";exp_continue}
"*password" {send "$password\r"}
}
expect eof
利用shell循環執行expect腳本
[root@salt-master tmp]# cat fenfa.sh
#!/bin/sh
. /etc/init.d/functions
if [ $# -ne 2 ];then
echo "usage:$0 file dir"
exit 1
fi
file=$1
dir=$2
cat /tmp/iplist |while read ip
do
expect fenfa.exp $file $ip $dir >/dev/null 2>&1
if [ $? -eq 0 ];then
action "$ip" /bin/true
else
action "$ip" /bin/false
fi
done
腳本中添加了function 系統函數庫,是爲了使用action,打印結果信息。
使腳本顯得更專業。
將/etc/hosts文件批量分發到所有服務器的/tmp目錄
[root@salt-master tmp]# sh fenfa.sh /etc/hosts /tmp
192.168.132.11 [ OK ]
192.168.132.10 [ OK ]
分發後查看
[root@salt-minion01 tmp]# ls -l
total 4
-rw-r--r-- 1 root root 243 Jun 21 20:48 hosts
[root@salt-minion02 tmp]# ls -l
total 4
-rw-r--r-- 1 root root 243 Jun 21 20:48 hosts
通過發送文件方式可以批量部署ssh免祕鑰。