使用expect執行動態指令碼

jeanron100發表於2015-08-05
在平時的工作中,如果接手的環境多了之後,每天去嘗試連線伺服器,都是例行的步驟,時間長了之後就會感覺這些工作都是繁瑣重複的工作,其實我們可以嘗試讓工作更簡化,更高效一些。
比如我們設定下面的場景,
我們存在伺服器A,這個伺服器可以連線到網路環境中的其它機器,我們假定這個機器就是中控機。
透過中控機連線到各個伺服器環境,有下面幾個步驟,
1)連線到某一臺伺服器B
2)檢視系統的版本資訊
3)檢視系統的核心資訊
4)切換到Oracle使用者下
5)檢視伺服器所使用的Oracle版本

因為切換使用者的原因,所以單純使用ssh來執行命令,第4,5步就沒法完成,這個時候我們可以有幾種思路來做,一種是透過連線工具錄製指令碼,比如secureCRT錄製一段指令碼,操作一遍之後,以後每次執行就需要重放指令碼即可。
如果受到工具的限制,或者覺得錄製指令碼也不夠動態,比如有100臺伺服器,我們就需要錄製100個指令碼,查詢,執行相比而言工作量還是不少,這個時候我們可以使用Linux中的expect命令來DIY
expect是RHEL6版本中自帶的一個實用工具,可以校驗上個命令執行後的結果集中的關鍵字,來靈活的執行各種批次處理任務。
expect的互動方式有兩種,一種需要以expect eof結尾,另外一種是interact結尾。
這兩種方式可以打個比方,比如我們把家比作伺服器A,朋友的家比作伺服器B,有一天我去給朋友送一個東西,可以把這個比作在伺服器B需要的的操作
如果我給朋友送完東西之後,想在朋友家裡吃個晚飯,然後一起看一晚上球賽,第二天再回家,這種情況就有點類似interact的方式。
如果我給朋友送完東西之後就回家,朋友邀請吃晚飯也婉拒,這種方式就類似expect eof.
我們來看幾個簡單的例子。
我們假設下面的指令碼為test.sh
需要在指令碼前宣告 #!/usr/bin/expect,然後使用spawn來啟動ssh連線,然後切換到oracle使用者,檢視系統的版本資訊,核心資訊,然後檢視oracle的版本資訊,最後退出,返回到最開始的session
#!/usr/bin/expect
spawn ssh 10.127.133.45
expect "#"
send "su - oracle\r"
send "cat /etc/issue \r"
send "uname -a \r"
send "sqlplus -v \r"
send "exit \r"
send "exit \r"
expect eof
執行命令 ./test.sh, 命令執行的輸出結果如下:
spawn ssh 10.xxxx.xxxx.45
Last login: Wed Aug  5 22:06:45 2015 from 10.xxxx.133.xxxx
[root@xxxx_xxxx_45 ~]# su - oracle
[oracle@BX_xxxx_45 ~]$ cat /etc/issue 
Red Hat Enterprise Linux Server release 6.3 (Santiago)
Kernel \r on an \m
[oracle@xxxx_xxxx_45 ~]$ uname -a 
Linux xxxx_xxxx 2.6.32-279.el6.x86_64 #1 SMP Wed Jun 13 18:24:36 EDT 2012 x86_64 x86_64 x86_64 GNU/Linux
[oracle@xxxx_xxxx_45 ~]$ sqlplus -v 
SQL*Plus: Release 11.2.0.4.0 Production
[oracle@xxxx_xxxx_45 ~]$ exit 
logout
[root@xxxx_xxxx_45 ~]# exit 
logout
Connection to 10.xxxx.xxxx.45 closed.
可以看到其實就是連線到目標環境中,執行完命令之後返回原來的session.
再來看一個interact的例子,比如我們存在大量的使用者,需要透過快捷方式登入到指定的機器上,檢視伺服器名,然後連入oracle使用者,檢視資料庫版本。
#!/usr/bin/expect
spawn ssh 10.xxxx.0.63
expect "#"
send "su - oracle\r"
send "cat /etc/issue \r"
send "uname -a \r"
send "cat /etc/hosts|grep `hostname` \r"
send "sqlplus -v \r"
interact
命令的執行結果如下:
spawn ssh 10.127.0.63
Last login: Wed Aug  5 22:43:58 2015 from 10.127.133.86
[root@xxxx ~]# su - oracle
[oracle@xxxx ~]$ cat /etc/issue 
Red Hat Enterprise Linux Server release 5.3 (Tikanga)
Kernel \r on an \m
[oracle@xxxx ~]$ uname -a 
Linux xxxx.com 2.6.18-194.el5 #1 SMP Tue Mar 16 21:52:39 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux
[oracle@xxxx ~]$ cat /etc/hosts|grep `hostname` ; 
10.127.xxxx.63     xxxx.com  #Primary
10.127.xxxx.82   xxxx.com  #Standby
[oracle@xxxx ~]$ sqlplus -v ;
ps -ef|grep smon 
SQL*Plus: Release 11.2.0.3.0 Production
這個時候我們已經連入了那個目標環境,可以繼續在這個基礎上進行其它的操作。
在這個基礎上稍微擴充套件一下,我們可以把expect和shell變數聯絡起來
比如我們有100臺伺服器,我們只需要輸入IP地址即可,然後後面會自動去切換使用者,檢查核心引數,系統引數等等。
只需要修改下面的兩個部分即可,整個指令碼一下子就動態起來了。
#!/usr/bin/expect
set ip_addr [lindex $argv 0] 
spawn ssh $ip_addr 
expect "#"
send "su - oracle\r"
send "cat /etc/issue \r"
send "uname -a \r"
send "cat /etc/hosts|grep `hostname` ; \r"
send "sqlplus -v ;\r"
send "ps -ef|grep smon \r"
interact

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-1763163/,如需轉載,請註明出處,否則將追究法律責任。

相關文章