使用expect執行動態指令碼

2021-09-22 19:20:53 字數 3531 閱讀 7263

在平時的工作中,如果接手的環境多了之後,每天去嘗試連線伺服器,都是例行的步驟,時間長了之後就會感覺這些工作都是繁瑣重複的工作,其實我們可以嘗試讓工作更簡化,更高效一些。

比如我們設定下面的場景,

我們存在伺服器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.***x.***x.45

last login: wed aug  5 22:06:45 2015 from 10.***x.133.***x

[root@***x_***x_45 ~]# su - oracle

[oracle@bx_***x_45 ~]$ cat /etc/issue 

red hat enterprise linux server release 6.3 (santiago)

kernel \r on an \m

[oracle@***x_***x_45 ~]$ uname -a 

linux ***x_***x 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@***x_***x_45 ~]$ sqlplus -v 

sql*plus: release 11.2.0.4.0 production

[oracle@***x_***x_45 ~]$ exit 

logout

[root@***x_***x_45 ~]# exit 

logout

connection to 10.***x.***x.45 closed.

可以看到其實就是連線到目標環境中,執行完命令之後返回原來的session.

再來看乙個interact的例子,比如我們存在大量的使用者,需要通過快捷方式登入到指定的機器上,檢視伺服器名,然後連入oracle使用者,檢視資料庫版本。

#!/usr/bin/expect

spawn ssh 10.***x.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@***x ~]# su - oracle

[oracle@***x ~]$ cat /etc/issue 

red hat enterprise linux server release 5.3 (tikanga)

kernel \r on an \m

[oracle@***x ~]$ uname -a 

linux ***x.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@***x ~]$ cat /etc/hosts|grep `hostname` ; 

10.127.***x.63     ***x.com  #primary

10.127.***x.82   ***x.com  #standby

[oracle@***x ~]$ 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 $ar** 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

shell指令碼巢狀執行expect命令

1.expect命令說明 為避免反覆呼叫,可以巢狀執行 相關命令 spawn 啟動乙個程式或程序 send 給程序或程式返回結果 expect 接受程式或程序輸出 interact 使使用者處於程序或程式的互動狀態,ssh登入後不自動登出 2.shell中巢狀expect命令 bin bash sq...

expect使用ssh登入指令碼

基礎篇 u s ssh spawn ssh l root 10.10.10.24 等待響應,第一次登入往往會提示是否永久儲存 rsa 到本機的 know hosts 列表中 等到回答後,在提示輸出密碼 之後就直接提示輸入密碼 expect yes no password host interact ...

mysql執行動態sql語句

今天oracle群上有人問mysql可不可以執行動態的sql語句,搜了一下,居然可以。set tsql select from companyinfo prepare stmt1 from tsql execute stmt1 set fid fid set table1 companyinfo s...