shell中的expect命令
原文https://blog.csdn.net/jxdl6655/article/details/78626749
expect可以實現shell實現不了的用戶交互的需求。expect可以將交互寫在一個腳本上,完成很多自動化的動作,比如ssh、ftp登陸等,都是需要交互需求的。expect是需要安裝的,直接yum??-y install expect安裝即可。
expect的四個關鍵命令為:spawn、expect、send、set,其中spawn是調用要執行的命令,expect是等待命令提示信息的出現也即捕捉用戶提示信息,send是發送需要交互的信息來替代手工的輸入,set則是輸入變量值。
一、expect關鍵語法
1、關鍵語法
[#!/usr/bin/expect] 這一行告訴操作系統腳本里的代碼使用那一個shell來執行。這里的expect其實和linux下的bash、windows下的cmd是一類東西。?注意:這一行需要在腳本的第一行。
spawn ?????????????調用要執行的命令
expect ??????????????只有spawn執行的命令的執行結果才被expect捕捉到,主要包括標準輸入的提示信息、eof和timeout。等待命令提示信息的出現,也就是捕捉用戶輸入的提示:
send?????????????????發送需要交互的值,替代了用戶手動輸入內容
set????????????????????設置變量值
interact?????????????執行完成后保持交互狀態,把控制權交給控制臺,這個時候就可以手工操作了。如果沒有這一句登錄完成后會退出,而不是留在遠程終端上。
expect eof ???????這個一定要加,與spawn對應表示捕獲終端輸出信息終止,類似于if....endif
PS:expect腳本必須以interact或expect eof結束,執行自動化任務通常expect eof就夠了。
2、常見設置
set timeout -1??????設置expect永不超時???
set timeout 300???設置expect 300秒超時,如果超過300沒有expect內容出現,則退出?????
PS:為什么要設置超時時間,因為默認時間是10s,則在交互執行的過程中,很可能會斷開,導致任務執行沒完成就終止。我司的一個從遠程ftp上同步文件的計劃任務總是執行終止,后來設置了超時時間為-1就可以了。
二、expect的用法示例
1、一個簡單的拉取文件的例子
---------------------?
?
2、一個小例子,用于linux下賬戶的建立:
以上腳本的注意點如下:
第3行: 對變量賦值的方法;
第4行: 默認情況下,timeout是10秒;
第6行: 參數的數目可以用$argc得到;
第11行:參數存在$argv當中,比如取第一個參數就是[lindex $argv 0];并且如果需要計算的話必須用expr,如計算2-1,則必須用[expr 2-1];
第13行:用spawn來執行一條shell命令,shell命令根據具體情況可自行調整;有文章說sudo要加-S,經過實際測試,無需加-S亦可;
第15行:一般情況下,如果連續做兩個expect,那么實際上是串行執行的,用例子中的結構則是并行執行的,主要是看匹配到了哪一個;在這個例子中,如果你寫成串行的話,即
expect "assword"
send "$passwd\n"
expect eof
send_user "eof"
那么第一次將會正確運行,因為第一次sudo時需要密碼;但是第二次運行時由于密碼已經輸過(默認情況下sudo密碼再次輸入時間為5分鐘),則不會提示用戶去輸入,所以第一個expect將無法匹配到assword,而且必須注意的是如果是spawn命令出現交互式提問的但是expect匹配不上的話,那么程序會按照timeout的設置進行等待;可是如果spawn直接發出了eof也就是本例的情況,那么expect "assword"將不會等待,而直接去執行expect eof。
這時就會報expect: spawn id exp6 not open,因為沒有spawn在執行,后面的expect腳本也將會因為這個原因而不再執行;所以對于類似sudo這種命令分支不定的情況,最好是使用并行的方式進行處理;
第17行:僅僅是一個用戶提示而已,可以刪除;
第18行:向spawn進程發送password;
第19行:使得spawn進程在匹配到一個后再去匹配接下來的交互提示;
第21行:eof是必須去匹配的,在spawn進程結束后會向expect發送eof;如果不去匹配,有時也能運行,比如sleep多少秒后再去spawn下一個命令,但是不要依賴這種行為,很有可能今天還可以,明天就不能用了;
3、下面這個例子比較特殊,在整個過程中就不能expect eof了
---------------------?
這個例子實際上是通過ssh去登錄遠程機器,并且在遠程機器上創佳一個目錄,我們看到在我們輸入密碼后并沒有去expect eof,這是因為ssh這個spawn并沒有結束,而且手動操作時ssh實際上也不會自己結束除非你exit;所以你只能expect bash的提示符,當然也可以是機器名等,這樣才可以在遠程創建一個目錄。注意,請不要用spawn mkdir tmpdir,這樣會使得上一個spawn即ssh結束,那么你的tmpdir將在本機建立。當然實際情況下可能會要你確認ssh key,可以通過并行的expect進行處理,不多贅述。
PS:在shell腳本中插入expect命令,格式為如下
總結
以上是生活随笔為你收集整理的shell中的expect命令的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: activiti5第一弹-----基本的
- 下一篇: 一个SPS + K2 + InfoPat