天天看點

expect 自動化互動軟體

一、expect簡介

expect是基于TCL的相對簡單的一種免費的腳本程式設計工具語言,用來實作自動和互動式任務程式進行通信,無需人的手工幹預,如:SSH、FTP等。這些程式正常情況下都需要手工進行互動,而使用expect就可以模拟人手工互動的過程,實作自動和遠端程式的互動,從來達到自動化運維的目的。

官方解釋:expect是一個用來實作自動互動功能的軟體套件(expect is a software suite for automating interactive tools)

expect支援Unix、linux、windows平台。

二、expect安裝

安裝expect軟體:

1、去expect官網下載下傳rpm包安裝:http://download.csdn.net/detail/wang7dao/4416172

# rpm -ihv expect-5.43.0-8.el5.i386.rpm

# rpm -ihv expect-devel-5.43.0-8.el5.i386.rpm

2、使用yum安裝 

#yum install expect -y

三、expect文法

expect程式工作流程:

sqawn啟動程序==》expect期待關鍵字==》send向程序發送字元==》退出結束。

spawn:是expect的初始指令,它用于啟動一個程序,之後所有expect操作都在這個程序中進行,如果沒有spawn語句,整個expect就無法執行,如:spawn ssh [email protected]  在spawn指令後面,直接加上要啟動的程序,指令等資訊

spawn支援的選項有:-open 啟動檔案程序,-ignore 忽略某些信号。

expect:使用方法:expect 表達式  動作  表達式 動作  .....

expect指令用于等候一個比對内容的輸出,一旦比對上就執行expect後面的動作或指令,這個指令接受幾個特有參數,用的最多的是-re,表示使用正規表達式的方式來比對,如:

spawn ssh [email protected]

expect "password:"  {send "123456\r"}

從例子看出,expect是依附于spawn指令的,當執行ssh指令後,expect就比對指令執行後的關鍵字:"password:",如果比對到關鍵字就會執行後面包含在{}括号中的send或exp_send動作,比對及動作可以放在二行,如不需要使用{}括号可以寫成多行:

expect "password:"

send "123456\r"

expect指令還有一種用法,它可以在一個expect比對中多次比對關鍵字,并給出處理動作,隻需要将關鍵字放在一個大括号中就可以了,當然還要有exp_continue:

expect {

  "yes/no"  { exp_send "yes\r";exp_continue }

"*password:"  { exp_send "123456\r" }  

}

exp_send 和send:

使用基本相同,是expect中的動作指令。它可以發送一些特殊符号如:\r(回車),\n(換行),\t(制表符),等,這些都與TCL中的特殊符号相同。

exp_continue:指令它要處于expect指令中,然後它屬于一個動作指令,完成的工作就是從頭開始周遊,也就是說如果沒有這個指令,比對第一個關鍵字以後就會繼續比對第二個關鍵字,但有個這個指令後,比對第一個關鍵字以後,第二次比對仍然從第一個關鍵字開始。

send_user:用來把後面的參數輸出到标準輸出中去,如:

send_user "please input password:"

這個語句就可以在标準輸出中列印please input password:字元了。

exit:直接退出腳本,也可以在退出前輸出一些資訊,如:

exit -onexit {

    send_user "say you baby!\n"

expect變量:

set: 變量名  變量值       #用來設定變量的方法

如:set file [lindex $argv 0]  #接收參數變量1

    set host [lindex $argv 1]  #接收參數變量2

    set password "123456"

puts $變量名     #讀取變量的方法

expect關鍵字:

eof:用于比對結束符

timeout:它是expect中的一個重要變量,它是一個全局性的時間控制開關。

如:set timeout 200

    -timeout 200

四、expect使用案列

列1:ftp拷貝檔案自動輸入密碼拷貝

<code>#!/usr/bin/expect   #聲明程式執行指令</code>

<code>set</code> <code>password 123456   </code><code>#設定密碼</code>

<code>#download</code>

<code>spawn </code><code>scp</code> <code>[email protected]:</code><code>/root/a</code><code>.wmv </code><code>/home/yangyz/</code>  <code>#生成程序連結遠端伺服器</code>

<code>set</code> <code>timeout 300  </code><code>#設定逾時時間</code>

<code>expect </code><code>"[email protected]'s password:"</code>  <code>#比對内容輸出</code>

<code>set</code> <code>timeout 300 </code>

<code>send </code><code>"$password\r"</code>  <code>#發送密碼給程序</code>

<code>send </code><code>"exit\r"</code>    <code>#發送退出指令</code>

<code>expect eof</code>

列2:自動ssh登陸

<code>#!/usr/bin/expect</code>

<code>spawn </code><code>ssh</code> <code>-p22 [email protected] </code><code>/sbin/ifconfig</code> <code>eth0</code>

<code>set</code> <code>timeout 30</code>

<code>expect {</code>

<code>-timeout 1</code>

<code>"yes/no"</code>  <code>{ exp_send </code><code>"yes\r"</code><code>;exp_continue }</code>

<code>"*password:"</code>  <code>{ exp_send </code><code>"123456\r"</code> <code>}</code>

<code>timeout  { puts </code><code>"expect was timeout by hehe."</code><code>;</code><code>return</code> <code>}</code>

<code>}</code>

<code>exit</code>

列3:ssh免密鑰分發

<code>[root@mail .</code><code>ssh</code><code>]</code><code># ssh-keygen -t rsa</code>

<code>Generating public</code><code>/private</code> <code>rsa key pair.</code>

<code>Enter </code><code>file</code> <code>in</code> <code>which</code> <code>to save the key (</code><code>/root/</code><code>.</code><code>ssh</code><code>/id_rsa</code><code>): </code>

<code>Enter passphrase (empty </code><code>for</code> <code>no passphrase): </code>

<code>Enter same passphrase again: </code>

<code>Your identification has been saved </code><code>in</code> <code>/root/</code><code>.</code><code>ssh</code><code>/id_rsa</code><code>.</code>

<code>Your public key has been saved </code><code>in</code> <code>/root/</code><code>.</code><code>ssh</code><code>/id_rsa</code><code>.pub.</code>

<code>The key fingerprint is:</code>

<code>80:a0:99:3a:46:32:ee:fb:d2:48:25:37:cc:a5:83:36 [email protected]</code>

<code>The key</code><code>'s randomart image is:'</code>

<code>+--[ RSA 2048]----+</code>

<code>|  .              |</code>

<code>| + . o           |</code>

<code>|*.+ + .          |</code>

<code>|=E O   .         |</code>

<code>|+o= o   S        |</code>

<code>|oo               |</code>

<code>|..o              |</code>

<code>| o..             |</code>

<code>| .o.             |</code>

<code>+-----------------+</code>

<code>[root@mail .</code><code>ssh</code><code>]</code><code># pwd</code>

<code>/root/</code><code>.</code><code>ssh</code>

<code>[root@mail .</code><code>ssh</code><code>]</code><code># ls</code>

<code>id_rsa  id_rsa.pub  known_hosts</code>

<code>[root@mail .</code><code>ssh</code><code>]</code><code># cp id_rsa.pub id_rsa.pub.bak</code>

<code>[root@mail .</code><code>ssh</code><code>]</code><code># mv id_rsa.pub authorized_keys</code>

<code>[root@mail .</code><code>ssh</code><code>]</code><code># mv id_rsa /server/</code>

<code>[root@mail .</code><code>ssh</code><code>]</code><code># cd /server/scripts/</code>

<code>[root@mail scripts]</code><code># cat sshkey.exp </code>

<code>#ssh key fenfa</code>

<code>set</code> <code>password </code><code>"123.com"</code>

<code>set</code> <code>s_file [lindex $argv 0]</code>

<code>set</code> <code>d_host [lindex $argv 1]</code>

<code>set</code> <code>d_dir [lindex $argv 2]</code>

<code>set</code> <code>timeout 10</code>

<code>spawn </code><code>scp</code> <code>-P 22 -r -p $s_file root@$d_host:$d_dir</code>

<code>-timeout 5</code>

<code>"yes/no"</code> <code>{send </code><code>"yes\r"</code><code>;exp_continue}</code>

<code>"*password:"</code> <code>{send </code><code>"$password\r"</code><code>}</code>

<code>timeout {puts </code><code>"connect to timeout"</code><code>;</code><code>return</code><code>}</code>

<code>exit</code> <code>-onexit {</code>

<code>send_user </code><code>"exit bye! \n"</code>

<code>[root@mail scripts]</code><code># cat sshkey_fenfa.sh </code>

<code>#!/bin/bash</code>

<code>#fenfa scripts</code>

<code>. </code><code>/etc/init</code><code>.d</code><code>/functions</code>

<code>for</code> <code>i </code><code>in</code> <code>`</code><code>cat</code> <code>/server/scripts/listip</code><code>`</code>

<code>do</code>

<code>expect sshkey.exp </code><code>/root/</code><code>.</code><code>ssh</code> <code>$i </code><code>/root</code> <code>&amp;&gt;</code><code>/dev/null</code>

<code>if</code> <code>[ $? -</code><code>eq</code> <code>0 ];</code><code>then</code>

<code>action </code><code>"$i"</code> <code>/bin/true</code>

<code>else</code>

<code>action </code><code>"$i"</code> <code>/bin/false</code>

<code>fi</code>

<code>done</code>

<code>[root@mail scripts]</code><code># cat listip </code>

<code>10.0.0.10</code>

<code>...</code>

<code>10.0.0.112</code>

<code>[root@mail scripts]</code><code># ssh 10.0.0.10</code>

<code>Last login: Tue Aug  1 15:57:20 2017 from 10.0.0.100</code>

<code>[root@zabbix ~]</code><code># ifconfig eth0</code>

<code>eth0      Link encap:Ethernet  HWaddr 00:0C:29:DB:44:29  </code>

<code>          </code><code>inet addr:10.0.0.10  Bcast:10.0.0.255  Mask:255.255.255.0</code>

<code>          </code><code>inet6 addr: fe80::20c:29ff:fedb:4429</code><code>/64</code> <code>Scope:Link</code>

<code>          </code><code>UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1</code>

<code>          </code><code>RX packets:15111544 errors:0 dropped:0 overruns:0 frame:0</code>

<code>          </code><code>TX packets:15940400 errors:0 dropped:0 overruns:0 carrier:0</code>

<code>          </code><code>collisions:0 txqueuelen:1000 </code>

<code>          </code><code>RX bytes:2595895595 (2.4 GiB)  TX bytes:2891681366 (2.6 GiB)</code>

<code>[root@zabbix ~]</code><code># ll ~/.ssh</code>

<code>總用量 12</code>

<code>-rw-r--r-- 1 root root 398 8月   1 14:57 authorized_keys</code>

<code>-rw-r--r-- 1 root root 398 8月   1 15:01 id_rsa.pub.bak</code>

<code>-rw-r--r-- 1 root root 391 8月   1 15:55 known_hosts</code>

列4:cisco交換機自動應用通路控制清單

<code>#telnet </code>

<code>set user </code><code>"pjycm"</code>

<code>set password </code><code>"[email protected]"</code>

<code>set command </code><code>"ip access-group 1 in"</code>

<code>set timeout 10</code>

<code>spawn telnet 10.0.0.1</code>

<code>        </code><code>"Username:"</code> <code>{send </code><code>"$user\r"</code><code>;exp_continue}</code>

<code>        </code><code>"Password:"</code> <code>{send </code><code>"$password\r"</code><code>;exp_continue}</code>

<code>        </code><code>"CM&gt;"</code> <code>{send </code><code>"en\r"</code><code>;exp_continue}</code>

<code>        </code><code>"Password:"</code> <code>{send </code><code>"[email protected]\r"</code><code>;exp_continue}</code>

<code>        </code><code>"CM#"</code> <code>{send </code><code>"conf t\r"</code><code>;exp_continue}</code>

<code>        </code><code>"CM(config)#"</code> <code>{send </code><code>"int vlan 10\r"</code><code>;exp_continue}</code>

<code>        </code><code>"CM(config-if)#"</code> <code>{send </code><code>"$command\r"</code><code>}</code>

腳本寫的比較簡單,如在工作中應用,應加入流程控制判斷語句!

本文轉自 80後小菜鳥 51CTO部落格,原文連結:http://blog.51cto.com/zhangxinqi/1952741

繼續閱讀