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"}
}
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 {條件表達式} {
指令
或
} 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案例
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
"*password" {send "$password\r"}
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
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:
/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
if { $argc != 3 } {
send_user "usage:expect $argv0 file ip dir"
set file [lindex $argv 0]
set host [lindex $argv 1]
set dir [lindex $argv 2]
spawn scp -P22 -r -p $file root@$host:$dir
利用shell循環執行expect腳本
[root@salt-master tmp]# cat fenfa.sh
. /etc/init.d/functions
if [ $# -ne 2 ];then
echo "usage:$0 file dir"
file=$1
dir=$2
expect fenfa.exp $file $ip $dir >/dev/null 2>&1
if [ $? -eq 0 ];then
action "$ip" /bin/true
else
action "$ip" /bin/false
fi
腳本中添加了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
通過發送檔案方式可以批量部署ssh免秘鑰。