shell脚本——expect命令
一、對(duì)expect的基本了解
?我們通過(guò)Shell可以實(shí)現(xiàn)簡(jiǎn)單的控制流功能,如:循環(huán)、判斷等。但是對(duì)于需要交互的場(chǎng)合則必須通過(guò)人工來(lái)干預(yù),有時(shí)候我們可能會(huì)需要實(shí)現(xiàn)和交互程序如telnet服務(wù)器等進(jìn)行交互的功能。而expect就使用來(lái)實(shí)現(xiàn)這種功能的工具。
?????? expect是一個(gè)免費(fèi)的編程工具語(yǔ)言,用來(lái)實(shí)現(xiàn)自動(dòng)和交互式任務(wù)進(jìn)行通信,而無(wú)需人的干預(yù)。expect是不斷發(fā)展的,隨著時(shí)間的流逝,其功能越來(lái)越強(qiáng)大,已經(jīng)成為系統(tǒng)管理員的的一個(gè)強(qiáng)大助手。expect需要Tcl編程語(yǔ)言的支持,要在系統(tǒng)上運(yùn)行expect必須首先安裝Tcl。
二、expect的安裝
expect是在Tcl基礎(chǔ)上創(chuàng)建起來(lái)的,所以在安裝expect前我們應(yīng)該先安裝Tcl。
(一)Tcl 安裝
主頁(yè):?http://www.tcl.tk
下載地址:?http://www.tcl.tk/software/tcltk/downloadnow84.tml
1.下載源碼包
?wget?http://nchc.dl.sourceforge.net/sourceforge/tcl/tcl8.4.11-src.tar.gz??
?
2.解壓縮源碼包?
tar?xfvz?tcl8.4.11-src.tar.gz??
?
3.安裝配置
注意:
1、安裝完畢以后,進(jìn)入tcl源代碼的根目錄,把子目錄unix下面的tclUnixPort.h copy到子目錄generic中。
2、暫時(shí)不要?jiǎng)h除tcl源代碼,因?yàn)閑xpect的安裝過(guò)程還需要用。
(二)expect 安裝 (需Tcl的庫(kù))
主頁(yè):?http://expect.nist.gov/
1.下載源碼包 wget?http://sourceforge.net/projects/expect/files/Expect/5.45/expect5.45.tar.gz/download
?
2.解壓縮源碼包
tar?xzvf?expect5.45.tar.gz??
?
3.安裝配置?
| shell腳本實(shí)現(xiàn)expect的安裝 |
| ######################################################## #(1)這部分實(shí)現(xiàn)expect的安裝 #(2)expect 需要 依賴tcl的庫(kù) #(3)expect的位置 /use/expect/bin/expect; tcl位置 /usr/tcl/bin/tclsh8.4 #(4)注意:腳本每執(zhí)行一次 就會(huì)安裝一次 ######################################################## function testInstal_pack() { echo -e "\033[32m-----------------------------------------------\033[0m" echo "This is going to install package $1!" if [ $1 == "tcl" ] then echo "tcl tcl" tar -xzf $TCLTAR_PATH -C $RUN_PATH cd $TCL_PATH/unix ./configure --prefix=/usr/tcl --enable-shared make && make install cp $TCL_PATH/unix/tclUnixPort.h $TCL_PATH/generic/ fi ? if [ $1 == "expect" ] then echo "aa" tar -xzf $EXPECTTAR_PATH -C $RUN_PATH cd $EXPECT_PATH ./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-tclinclude=$TCL_PATH/generic make && make install ln -s /usr/tcl/bin/expect /usr/expect/bin/expect fi } #testInstal_pack openssl testInstal_pack tcl testInstal_pack expect |
三、expect的原理
| Linux expect 腳本的使用 |
| Expect的原理: ?????Expect腳本語(yǔ)言自動(dòng)提交輸入到交互程序,它的工作原理是等待特定字符串,并發(fā)送或者響應(yīng)相應(yīng)的字符串。以下四個(gè)expect命令用于任何自動(dòng)化的過(guò)程。 1、spawn:啟動(dòng)命令 2、expect:等待來(lái)自進(jìn)程的特定的字符串 3、send:發(fā)送字符串到進(jìn)程 4、interact:允許用戶交互 |
3.1 首行加上/usr/bin/expect 但是在根據(jù)上述方式安裝后 應(yīng)該為#!/usr/expect/bin/expect
3.2?spawn: 后面加上需要執(zhí)行的shell命令,比如說(shuō)spawn sudo touch testfile
3.3 expect:?只有spawn執(zhí)行的命令結(jié)果才會(huì)被expect捕捉到,因?yàn)閟pawn會(huì)啟動(dòng)一個(gè)進(jìn)程,只有這個(gè)進(jìn)程的相關(guān)信息才會(huì)被捕捉到,主要包括:標(biāo)準(zhǔn)輸入的提示信息,eof和timeout。
3.4 send和send_user:send會(huì)將expect腳本中需要的信息發(fā)送給spawn啟動(dòng)的那個(gè)進(jìn)程,而send_user只是回顯用戶發(fā)出的信息,類似于shell中的echo而已。
四、expect的使用實(shí)例
1、使用expect工具ssh登錄遠(yuǎn)程服務(wù)器并執(zhí)行命令操作
遠(yuǎn)程交互從服務(wù)器A上ssh到服務(wù)器B上,然后執(zhí)行服務(wù)器B上的命令
| #!/usr/expect/bin/expect -f ? set ipaddress [lindex $argv 0] set port [lindex $argv 1] set username [lindex $argv 2] set passwd [lindex $argv 3] set timeout 30 ? if {$argc != 4} { send "usage ./account.sh \$ipaddress \$port \$username \$passwd\n" exit } ? spawn ssh $ipaddress -p$port -l$username expect { "yes/no" { send "yes\r";exp_continue } "password:" { send "$passwd\r" } } expect -re "\](\$|#) " send "iptables -F\r" expect -re "\](\$|#) " send "exit\r" |
4.1 默認(rèn)情況下 timeout是10秒,但是在ssh遠(yuǎn)程登錄的時(shí)候建議改為30秒,否則會(huì)報(bào)錯(cuò)“expect: spawn id exp4 not open,”
4.2 輸入的參數(shù)的數(shù)目,可以通過(guò)$argc得到;
4.3 參數(shù)存在$argv當(dāng)中,比如取第一個(gè)參數(shù)就是[lindex $argv 0];并且如果需要計(jì)算的話必須用expr,如計(jì)算2-1,則必須用[expr 2-1];
4.4 下面我們來(lái)看一些expect的一些內(nèi)部參數(shù):
exp_continue [-continue_timer]
???????????? The command exp_continue allows expect itself to continue executing rather than returning as it? normally
???????????? would.? By? default? exp_continue? resets the timeout timer. The -continue_timer flag prevents timer from
???????????? being restarted.
exp_version [[-exit] version]
???????????? is useful for assuring that the script is compatible with the current version of Expect.
?????????????With? no? arguments, the current version of Expect is returned.? This version may then be encoded in your
???????????? script.? If you actually know that you are not using features of recent versions, you can specify an ear-
???????????? lier version.
執(zhí)行結(jié)果如下:
| [root@slave1 workspace]# ./dotask.exp 192.168.1.93 usage ./account.sh $ipaddress $port $username $passwd [root@slave1 workspace]# ./dotask.exp 192.168.1.93 22 root asdfgh spawn ssh 192.168.1.93 -p22 -lroot root@192.168.1.93's password: Last login: Fri Jun 15 15:08:49 2018 from 192.168.1.177 [root@J01051386 ~]# iptables -F [root@J01051386 ~]# [root@slave1 workspace]# |
?
| 參考的鏈接:http://blog.sina.com.cn/s/blog_5432f2730100vcql.html |
| Expect說(shuō)白了就是一個(gè)實(shí)現(xiàn)人機(jī)交互的命令工具,可以抓取和相應(yīng)用戶輸入,也可以模擬用戶輸出。 ? 比如你有n臺(tái)服務(wù)器需要維護(hù),要登錄到所有的服務(wù)器上執(zhí)行某項(xiàng)操作(如添加用戶、修改一個(gè)用戶的密碼),如果按傳統(tǒng)方法,一個(gè)一個(gè)去登錄敲命令那就太麻煩了。可以通過(guò)expect寫成shell腳本來(lái)批量處理,具體如下: 如果系統(tǒng)里沒(méi)有expect請(qǐng)自行到官網(wǎng)下載安裝:http://expect.sourceforge.net/ 1、創(chuàng)建服務(wù)器列表配置文件: [root@localhost ~]# vi server_list.conf 192.168.0.10 22 root 123456 192.168.0.11 22 root 123456 192.168.0.12 60008 root 123456 ? 說(shuō)明:配置文件有4列,以空格分割:服務(wù)器IP ssh端口號(hào) 用戶名 密碼 2、編寫expect腳本: [root@localhost ~]# vi dotask.exp #!/usr/bin/expect -f set ipaddress [lindex $argv 0] set port [lindex $argv 1] set username [lindex $argv 2] set passwd [lindex $argv 3] set timeout 30 spawn ssh $ipaddress -p$port -l$username expect { "yes/no" { send "yes\r";exp_continue } "password:" { send "$passwd\r" } } expect -re "\](\$|#) " send "touch test \r" expect -re "\](\$|#) " send "exit\r" ? 說(shuō)明:這里只實(shí)現(xiàn)了登錄服務(wù)器后在當(dāng)前目錄創(chuàng)建了一個(gè)test文件,具體需求請(qǐng)自行修改添加命令 ? 3、批量執(zhí)行 其實(shí)只要寫好第2步的腳本就可以通過(guò)下面命令執(zhí)行一臺(tái)服務(wù)器的處理: [root@localhost ~]# expect?dotask.exp?192.168.0.10 22 root 123456 但為了能批量處理n臺(tái),再寫個(gè)shell腳本就行了,如下: [root@localhost ~]# vi doexcute.sh #!/bin/bash ? filename="server_list.conf" while read line do ??#echo $line; ??expect?dotask.exp$line done < $filename ? 說(shuō)明:讀取配置文件,循環(huán)執(zhí)行 最后,其他具體的使用方法參見(jiàn)expect手冊(cè) ? ================================================= 實(shí)用工具:autoexpect ================================================= 如果自己懶得寫expect代碼,則可以用autoexpect生成。autoexpect工具是用expect寫成的一個(gè)工具腳本,它可以錄制你執(zhí)行的操作、命令、鍵盤輸入等等,之后自動(dòng)生成expect腳本。 autoexpect腳本代碼見(jiàn):http://blog.sina.com.cn/s/blog_5432f2730100vcqn.html 使用方法: 1、把上面鏈接里的autoexpect代碼保存成文件:autoexpect.exp 2、執(zhí)行下面命令進(jìn)行錄制: [root@localhost ~]# expect?autoexpect.exp -p ?說(shuō)明:執(zhí)行完上面命令后就可以進(jìn)行你需要的操作了,需要結(jié)束錄制時(shí),用exit退出即可。 3、錄制完后,會(huì)在當(dāng)前目錄生成一個(gè)script.exp文件,這個(gè)文件就是錄制好的expect腳本了。是直接拿來(lái)使用,還是再改改,或是學(xué)習(xí)用,就看你自己的需要了。 |
?
2、在shell語(yǔ)句中完成賦值操作,并做判斷
http://blog.51cto.com/maomaochong/1690753
注意:
1.?if判斷中[]與if間需要有空格;
2.?if判斷語(yǔ)句中判斷語(yǔ)句與[]兩邊都要有空格;
3.?If判斷語(yǔ)句中=號(hào)兩邊要有空格;
例如##ping -c 3 -i 0.1 192.168.1.32 && result=0||result=1;if [ "${result}" ?= ?0 ];then echo success;fi
例如:當(dāng)查看文件中是否有TLSCACertificatePath 開(kāi)頭的行,若有退出程序,若無(wú)則在最后一行加入。
cat sldap.conf|grep ^TLSCACertificatePath && result=0||result=1;echo ${result};if [ "${result}" = 0 ];then exit 1;else sed -i '$a TLSCACertificatePath' sldap.conf;fi
例如:當(dāng)查看文件中是否有TLSCACertificatePath 開(kāi)頭的行,若有不做處理,若無(wú)則在最后一行加入。
cat sldap.conf|grep ^TLSCACertificatePath && result=0||result=1;echo ${result};if [ "${result}" = 1 ];then sed -i '$a TLSCACertificatePath' sldap.conf;fi
Shell腳本中expect寫入最終格式(注意路徑和轉(zhuǎn)義):
send "cat $SERVERLDAP_PATH/sldap.conf|grep ^TLSCACertificatePath && result=0||result=1;if \[ \"$\{result\}\" = 1 \];then sed -i '\$a TLSCACertificatePath /usr/local/etc/openldap/certs' $SERVERLDAP_PATH/sldap.conf;fi\r"
五、shell腳本調(diào)用expect腳本(即.sh文件調(diào)用.exp文件)
| [root@slave1 workspace]# cat test.sh |
| #!/bin/sh ./dotask.exp 192.168.1.93 22 root asdfgh |
| [root@slave1 workspace]# cat dotask.exp |
| 代碼見(jiàn) 四、expect的使用實(shí)例1 |
六、shell腳本調(diào)用shell腳本(即.sh文件調(diào)用.sh文件)
https://blog.csdn.net/simple_the_best/article/details/76285429
| hello.sh |
| #!/bin/bash wor="world" echo "hello `source ./world.sh`" |
| world.sh |
| #!/bin/bash echo $wor |
參考鏈接:
http://blog.sina.com.cn/s/blog_5432f2730100vcql.html
https://www.cnblogs.com/lixigang/articles/4849527.html
https://blog.csdn.net/nero_g/article/details/53945654
總結(jié)
以上是生活随笔為你收集整理的shell脚本——expect命令的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: shell脚本——实现简单的功能
- 下一篇: Mysql —— linux下使用c语言