Expect基本用法與介紹

比如連接SSH、FTP遠程連接等,正常情況下都需要手工與之交互,而使用Expect就可以模擬手工交互的過程,實現自動與遠端程序的交互,從而達到自動化運維的目的
Expect的自動交互工作流程簡要說明:
spawn啓功指定進程——>expect獲取期待的關鍵字——>send向指定進程發送指定字符——>進程執行完畢,退出結束。


在spawn命令後,直接加上要執行的命令或程序(例如ssh命令)等,除此之外,sqawn還支持如下一些選項.
-open:表示啓動文件進程
-ignore:表示忽略某些信號

expect命令的作用就是獲取spawn命令執行後的信息,看看是否和其事先指定的相匹配,一旦匹配上指定的內容就執行expect後面的動作
-re:表示使用正則表達式的方法來匹配
#如果匹配到了指定的password字符串,則會執行緊跟其後包含在{}(大括號)中的send或exp_send動作,匹配的動作也可以放在下一行,這樣就不需要使用{}(大括號)了。
expect命令可以在一個expect匹配中多次匹配不同的字符串,並給出不同的處理動作,此時只需要將匹配的所有字符串放在一個{}(大括號)中就可以了,當然還要藉助exp_continue指令實現繼續匹配。



例子:
#!/usr/bin/expect
#第一種:
#spawn ssh [email protected] uptime
#expect "*password"
#send "123456\n"
#expect eof

#第二種:
spawn ssh [email protected] uptime
expect {
    "yes/no"    {exp_send "yes\r";exp_continue}
    "*password" {exp_send "123456\r"}
    }
expect eof

#說明:
#exp_send和send類似,後面的\r(回車)和\n(換行)類似
#expect{}(起始大括號前要有空格),類型多行expect.
#匹配多個字符串,需要在多次匹配並執行動作後,加上exp_continue.最後一個的結尾就不需要加上exp_continue了,因爲都匹配完成了。
#執行腳本:expect line.exp

[root@web01 /server/scripts/10]# cat user.sh
#!/bin/bash
read -p 'Please input your username:' name
read -p 'Please input your password:' pass
read -p 'Please input your email:' mail
echo -n "your name is $name,"
echo -n "your password is $pass,"
echo "your email is $mail."
[root@web01 /server/scripts/10]# cat user.exp 
#!/usr/bin/expect
spawn /bin/bash user.sh
expect {
    "username" {exp_send "liucongcong\r";exp_continue}
    "*pass*"   {send "123456\r";exp_continue}
    "*mail*"   {exp_send "[email protected]\r"}
}
expect eof
[root@web01 /server/scripts/10]# expect user.exp 
spawn /bin/bash user.sh
Please input your username:liucongcong
Please input your password:123456
Please input your email:[email protected]
your name is liucongcong,your password is 123456,your email is [email protected].



send -i :指定spawn_id,用來向不同的spawn_id進程發送命令,是進行多程序控制的參數。
send -s:s代表slowly,即控制發送的速度,使用的時候要與expect中的變量send_slow相關聯


send_user命令可用來打印Expect腳本信息,類似Shell裏的echo命令,默認的send、exp_send命令都是將字符串輸出到Expect程序中去。


[root@web01 /server/scripts/10]# cat user.exp 
#!/usr/bin/expect
send_user "I am liucongcong.\n"
send_user "My blog is https://blog.csdn.net/qq_43011640\n"
[root@web01 /server/scripts/10]# expect user.exp 
I am liucongcong.
My blog is https://blog.csdn.net/qq_43011640


exit 
exit命令的功能類似於shell中的exit,直接退出Expect腳本,除了最基本的退出腳本功能之外,還可以利用這個命令對腳本做一些關閉前的清理和提示等工作,比如
[root@web01 /server/scripts/10]# cat user.exp 
#!/usr/bin/expect
send_user "I am liucongcong.\n"
send_user "My blog is https://blog.csdn.net/qq_43011640\n"
exit -onexit {
    send_user "Good bye.\n"
}
[root@web01 /server/scripts/10]# expect user.exp 
I am liucongcong.
My blog is https://blog.csdn.net/qq_43011640
Good bye.


Expect 程序變量
set 變量名   變量值
set password "123456"
打印變量
puts  $變量值
特殊參數變量
在Expect裏也有與Shell腳本里的$0、$1、$#等類似的特殊參數變量,用於接收及控制Expect腳本傳參
在Expect中$argv表示參數數組,可以使用[lindex $argv n]接收Expect腳本傳參,n從0開始,分別表示第一個[lindex $argv 0]參數、第二個[lindex $argv 1]參數、第三個[lindex $argv 2]參數.........
$argc表示傳參的個數,$argv0表示腳本的名字
[root@web01 /server/scripts/10]# cat user.exp 
#!/usr/bin/expect
set file [lindex $argv 0]
set host [lindex $argv 1]
set dir  [lindex $argv 2]
puts "$file\t$host\t$dir"
puts $argc
puts $argv0
[root@web01 /server/scripts/10]# expect user.exp user.txt 10.0.0.3 /opt
user.txt	10.0.0.3	/opt
3
user.exp

if 條件語句
if { 條件表達式 } {
      指令
      }
 或者
 if { 條件表達式 } {
       指令
 } else {
     指令
 }
 
[root@web01 /server/scripts/10]# cat user.exp 
#!/usr/bin/expect
if {$argc != 26 } {
    puts "bad"
} else {
    puts "good"
}
[root@web01 /server/scripts/10]# expect user.exp {a..z}
good
[root@web01 /server/scripts/10]# expect user.exp 1
bad

eof(end-of-file)關鍵字用於匹配結束符
timeout 是 Expect中的一個控制時間的關鍵字變量,它是一個全局性的時間控制開關,可以通過爲這個變量賦值來規定整個Expect操作的時間,注意這個變量是服務於Expect全局的,而不是某一條命令,即使命令沒有任何錯誤,到了時間仍然會激活這個變量,此外,到時間後還會激活一個處理及提示信息開關
[root@web01 /server/scripts/10]# cat user.exp
#!/usr/bin/expect
spawn ssh [email protected] uptime
set timeout 30
expect "yes/no" {exp_send "yes\r";exp_continue}
expect timeout  {puts "Request timeout by lcc.";return}
[root@web01 /server/scripts/10]# expect use.exp
spawn ssh [email protected] uptime
[email protected]'s password: Request timeout by lcc

例子:
自動化部署SSH密鑰認證
[root@web01 ~]# ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa > /dev/null 2>&1
[root@web01 ~]# cat ansible.sh
#!/bin/bash
##############################################################
# File Name: ansible.sh
# Time: 2019-11-10-16:11:09
# Author: lcc
# Organization: www.lcc.com
##############################################################
for n in 8 51 61
do
    expect ansible.exp ~/.ssh/id_dsa.pub 10.0.0.$n
done
[root@web01 ~]# cat ansible.exp
#!/usr/bin/expect
if { $argc != 2 } {
    send_user "usage: expect expect.exp file host\n"
    exit
}
set file [lindex $argv 0]
set host [lindex $argv 1]
set password "123456"
spawn ssh-copy-id -i $file "-p 22 root@host"
expect {
    "yes/no"   {send "yes\r";exp_continue}
    "*password" {send "$password\r"}
}
expect eof
[root@web01 ~]# sh ansible.sh


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