通過expect scp 命令分發檔案到其它機器

2021-07-23 11:45:32 字數 3322 閱讀 8791

1. expect是基於tcl演變而來的,所以很多語法和tcl類似,基本的語法如下所示:

1.1 首行加上/usr/bin/expect

1.2 spawn: 後面加上需要執行的shell命令,比如說spawn sudo touch testfile

1.3 expect: 只有spawn執行的命令結果才會被expect捕捉到,因為spawn會啟動乙個程序,只有這個程序的相關資訊才會**捉到,主要包括:標準輸入的提示資訊,eof和timeout。

1.4 send和send_user:send會將expect指令碼中需要的資訊傳送給spawn啟動的那個程序,而send_user只是回顯使用者發出的資訊,類似於shell中的echo而已。

2. 乙個小例子,用於linux下賬戶的建立:

filename: account.sh,可以使用./account.sh newaccout來執行;

1 #!/usr/bin/expect

23 set passwd "mypasswd"【這個是你設定的密碼】

4 set timeout 60

56 if

1011 set user [lindex $argv [expr $argc-1]]

1213 spawn sudo useradd -s /bin/bash -g mygroup -m $user

1415 expect

21     eof

22    

25 }

2627 spawn sudo passwd $user

28 expect

33     eof

34    

37 }

3839 spawn sudo smbpasswd -a $user

40 expect

45     eof

46    

49 }

3. 注意點:

第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下乙個命令,但是不要依賴這種行為,很有可能今天還可以,明天就不能用了;

4. 其他

下面這個例子比較特殊,在整個過程中就不能expect eof了:

1  #!/usr/bin/expect

23  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進行處理,不多贅述。

5.通過expect  scp把檔案分發到其他機器上,copy.sh**如下:

#!/usr/bin/expect

#通過ssh複製分發檔案

set filename test.txt

set filepath /data/cpp

set timeout 15 

set host2 10.******

set host3 10.******

set host4 10.******

set username hadoop

set password ********

spawn scp $filepath/$filename  $username@$host2:$filepath/$filename

expect "password:"

send "$password\r"

expect eof

spawn scp $filepath/$filename  $username@$host3:$filepath/$filename

expect "password:"

send "$password\r"

expect eof

spawn scp $filepath/$filename  $username@$host4:$filepath/$filename

expect "password:"

send "$password\r"

expect eof

exit

然後執行 expect copy.sh命令即可

iOS 蘋果企業證書通過網頁分發安裝app

這樣就可以將這個 鏈結發給使用者,非常方便,有木有感覺像apk的安裝方式哦o o哈哈 1.ipa和plist的生成步驟 選擇外接裝置選項 實際有無裝置無關 將程式archive。選擇ad hoc用於分發。選擇自己的企業級證書。2.構建 將這些專案上傳到您 上已鑑定的使用者可以訪問的區域 設定伺服器 ...

iOS 蘋果企業證書通過網頁分發安裝app

1.ipa和plist的生成步驟 選擇外接裝置選項 實際有無裝置無關 將程式archive。選擇ad hoc用於分發。選擇自己的企業級證書。2.構建 設定伺服器 mime 型別 您可能需要配置您的 web 伺服器以便正確地傳輸清單檔案和應用程式檔案。對於 os x server,將以下 mime 型...

iOS 蘋果企業證書通過網頁分發安裝app

1.ipa和plist的生成步驟 選擇外接裝置選項 實際有無裝置無關 將程式archive。選擇ad hoc用於分發。選擇自己的企業級證書。2.構建 將這些專案上傳到您 上已鑑定的使用者可以訪問的區域 設定伺服器 mime 型別 您可能需要配置您的 web 伺服器以便正確地傳輸清單檔案和應用程式檔案...