歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> expect在Linux下的應用

expect在Linux下的應用

日期:2017/2/28 14:55:14   编辑:Linux教程

先來看一段代碼:

  1. #!/usr/bin/expect
  2. set timeout 30
  3. spawn ssh -l root 192.168.1.188
  4. expect "password:"
  5. send "abc123456\r"
  6. interact

對這6行進行下解釋:

第1行[#!/usr/bin/expect]
這一行告訴操作系統腳本裡的代碼使用那一個shell來執行。這裡的expect其實和linux下的bash、windows下的cmd是一類東西。 這一行需要在腳本的第一行。
第2行[set timeout 30]
基本上認識英文的都知道這是設置超時時間的,現在你只要記住他的計時單位是:秒
第3行 [spawn ssh -l username 192.168.1.188]
spawn是進入expect環境後才可以執行的expect內部命令,如果沒有裝expect或者直接在默認的SHELL下執行是找不到spawn命 令的。所以不要用 “which spawn“之類的命令去找spawn命令。好比windows裡的dir就是一個內部命令,這個命令由shell自帶,你無法找到一個dir.com 或 dir.exe 的可執行文件。 它主要的功能是給ssh運行進程加個殼,用來傳遞交互指令。
第4行[expect "password:"]
這裡的expect也是expect的一個內部命令,有點暈吧,expect的shell命令和內部命令是一樣的,但不是一個功能,習慣就好了。這個命 令的意思是判斷上次輸出結果裡是否包含“password:”的字符串,如果有則立即返回,否則就等待一段時間後返回,這裡等待時長就是前面設置的30 秒
第5行[send "abc123456\r"]
這裡就是執行交互動作,與手工輸入密碼的動作等效。
溫馨提示: 命令字符串結尾別忘記加上“\r”,如果出現異常等待的狀態可以核查一下。
第6行[interact]
執行完成後保持交互狀態,把控制權交給控制台,這個時候就可以手工操作了。如果沒有這一句登錄完成後會退出,而不是留在遠程終端上。

在Linux下,執行ssh登陸或者是scp復制文件的時候可以使用到該命令,實現自動輸入密碼。

案例1:遠程執行命令

  1. #!/usr/bin/expect -f
  2. set timeout 30
  3. spawn ssh -l root 192.168.1.188
  4. expect {
  5. "yes/no" { send "yes\r";exp_continue }
  6. "password:" { send "abc123456\r" }
  7. }
  8. expect -re "\](\$|#) "
  9. send "bash /root/test.sh \r"
  10. expect -re "\](\$|#) "
  11. send "exit\r"

該代碼的功能是執行遠程服務器上的/root/test.sh腳本,參數“-re”是匹配正則表達式。可以寫多行send,執行多個命令。該腳本的另一種寫法

  1. #!/bin/bash
  2. expect -c "
  3. spawn ssh [email protected] \"ifconfig;whoami;pwd;echo hello;\"
  4. expect {
  5. \"*assword\" {set timeout 30; send \"abc123456\r\";}
  6. \"yes/no\" {send \"yes\r\"; exp_continue;}
  7. }
  8. expect eof
  9. "

參數“-c”是指在命令行執行expect。把要執行的命令用分號隔開了。並且執行過程中沒有shell提示符的,有興趣的你可以測試下。

案例2:批量處理

在需要管理大量的Linux服務器時,可以這樣做:

1.host.list

  1. 192.168.1.1 22 root abc1
  2. 192.168.1.2 22 root abc2
  3. 192.168.1.3 22 root abc3
  4. 192.168.1.4 22 root abc4
  5. 192.168.1.5 22 root abc5
  6. 192.168.1.6 22 root abc6
  7. 192.168.1.7 22 root abc7
  8. 192.168.1.8 22 root abc8

我們把服務器的IP地址、端口號、用戶名、密碼一起放在host.list文件裡,按行排列。

下面來看看腳本文件main.exp

  1. #!/usr/bin/expect -f
  2. set ipaddress [lindex $argv 0]
  3. set port [lindex $argv 1]
  4. set username [lindex $argv 2]
  5. set passwd [lindex $argv 3]
  6. set timeout 30
  7. spawn ssh $ipaddress -p$port -l$username
  8. expect {
  9. "yes/no" { send "yes\r";exp_continue }
  10. "password:" { send "$passwd\r" }
  11. }
  12. expect -re "\](\$|#) "
  13. send "bash /root/test.sh \r"
  14. expect -re "\](\$|#) "
  15. send "exit\r"

來做一個while循環:whi.sh

  1. #!/bin/bash
  2. host="host.list"
  3. while read line
  4. do
  5. expect main.exp $line
  6. done < $host

把以上腳本都賦予執行權限,就可以了。

案例3:scp文件傳輸

  1. expect -c "
  2. spawn scp [email protected]:/root/file1.tgz /root
  3. expect {
  4. \"*assword\" {set timeout 300; send \"abc123456\r\";}
  5. \"yes/no\" {send \"yes\r\"; exp_continue;}
  6. }
  7. expect eof
  8. "

同樣的原理,也可以做循環進行批量管理,還可以更簡化腳本,也不多說明了,有興趣的同學可以多嘗試下。使用expect進行自動輸入密碼登陸,基本多用於批量管理。也還算方便。關於批量管理有多種方法,可以在主機之間建立ssh信任機制,也可以免密碼登陸管理等。還可以使用sshpass(外部命令)這個命令進行帶密碼在腳本裡執行自動輸入密碼。

Copyright © Linux教程網 All Rights Reserved