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是一類東西。 注意:這一行需要在指令碼的第一行。
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、乙個簡單的拉取檔案的例子
#!/usr/bin/expect -f
set passwd "123456" ##這個是你設定的密碼
set timeout -1 ##設定超時時間
spawn sftp -p 2022 [email protected]
expect "password:"
send "$passwd\r"
expect "sftp>"
send "get -r data/201711*\r"
expect "sftp>"
send "exit\r"
interact
2、乙個小例子,用於linux下賬戶的建立:
1 #!/usr/bin/expect
2 3 set passwd "mypasswd"
4 set timeout 60
5 6 if
10 11 set user [lindex $argv [expr $argc-1]]
12 13 spawn sudo useradd -s /bin/bash -g mygroup -m $user
14 15 expect
21 eof
22
25 }
26 27 spawn sudo passwd $user
28 expect
33 eof
34
37 }
38 39 spawn sudo smbpasswd -a $user
40 expect
45 eof
46
49 }
以上指令碼的注意點如下:
第3行: 對變數賦值的方法;
第4行: 預設情況下,timeout是10秒;
第6行: 引數的數目可以用$argc得到;
第11行:引數存在$argv當中,比如取第乙個引數就是[lindex $argv 0];並且如果需要計算的話必須用expr,如計算2-1,則必須用[expr 2-1];
第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進行處理,不多贅述。1 #!/usr/bin/expect
2 set mypassword=123456
3 set timeout 30
4 spawn ssh 10.192.224.224
5 expect "password:"
6 send "mypassword\n"
7 expect "*$"
8 send "mkdir tmpdir\n"
9 expect "*$"
ps:在shell指令碼中插入expect命令,格式為如下
#!/bin/sh
expect <"
send "mkdir ***xx\r"
send "exit\r"
expect eof
! ##結尾
shell指令碼之expect語句
在編寫shell指令碼時,我們可能會遇到一些互動式的情況,如passwd ssh等等指令碼時,常常需要手動進行互動。這樣,原本為了實現自動部署的指令碼顯得有些不大方便,這時你就會用上expect命令了。expect命令可以幫你把互動式命令變成非互動式。expect 有期待 期望的中文意思。正如它的中...
shell自動互動之expect指令碼 轉
linux expect詳解 ssh自動登入 shell指令碼實現ssh自動登入遠端伺服器示例 usr bin expect spawn ssh root 192.168.22.194 expect password send 123 r expect interact expect是乙個用來處理互...
expect常用方法shell
1.usr bin expect 告訴作業系統指令碼裡的 使用那乙個 shell 來執行。這裡的 expect 其實和 linux 下的 bash windows 下的 cmd 是一類東西。注意 這一行需要在指令碼的第一行,從而告知作業系統採用 expect 作為 shell 執行指令碼。注意 當使...