shell學習之四 expect命令

2021-08-11 06:40:19 字數 3538 閱讀 6223

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了

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 "*$"

這個例子實際上是通過ssh去登入遠端機器,並且在遠端機器上創佳乙個目錄,我們看到在我們輸入密碼後並沒有去expect eof,這是因為ssh這個spawn並沒有結束,而且手動操作時ssh實際上也不會自己結束除非你exit;所以你只能expect bash的提示符,當然也可以是機器名等,這樣才可以在遠端建立乙個目錄。注意,請不要用spawn mkdir tmpdir,這樣會使得上乙個spawn即ssh結束,那麼你的tmpdir將在本機建立。當然實際情況下可能會要你確認ssh key,可以通過並行的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 執行指令碼。注意 當使...