1. 程式人生 > >0 SHELL訓練營--day10_expect

0 SHELL訓練營--day10_expect

expect

expect 是一個免費的程式設計工具語言,對於互動的場合,實現自動和互動式任務進行通訊,而無需人的干預。
expect 安裝:yum install -y expect
expect 指令碼定義:預設以“.expect” 為字尾。指令碼語言在首行要指明語言工具:#!/usr/bin/expect
expect 由一系列expect-send對組成:expect等待輸出中輸出特定的字元,通常是一個提示符,然後send 傳送特定的響應。

  • 變數定義

    expect通過 set 命令定義變數。
    變數來源有兩種形式:

    1. set a 1 直接定義 變數和 值。
    2. set host [lindex $argv 0] 通過獲取指令碼傳遞過來的引數定義變數,實現互動。
  • spawn建立子程序

    expect 通過 spawn 建立一個執行program args命令的程序。它的stdin,stdout,stderr(標準輸入,標準輸出,標準錯誤輸出)都連到Expect。
    如通過spawn建立一個SSH連線,並通過 expect捕捉stdout標準輸出資訊,再通過 send 向spawn生成的程序 輸入 相關命令。

    #1登入示例
    #!/usr/bin/expect
    set use root
    set passwd 123456!
    set host 192.168.20.2
    spawn ssh 
    [email protected]
    $host expect { "yes/no" { send "yes\r"} # 遇到包含"yes/no"的標準輸出資訊時,通過send傳送確認資訊。 "password:" { send "$passwd\r" } } expect "#*" send "pwd\r"
  • 延時功能

    需要注意的是spawn是expect環境下,expect語言內部命令。它生成的程序執行完成後,會自動退出。
    通過spawn生成的程序,可通過send向遠端的伺服器傳遞命令,這個命令執行是遠端主機生成的tty視窗執行,而不是在本地的spawn程序中執行。這兩個程序,在命令的執行時間 ,會產生衝突。
    如:spawn完成任務後,退出程序,從而關閉生成的遠端連線TTY視窗,但這視窗下的命令未完成,就會達不到任務需要的效果。
    可通過 設定 spawn延時來 等待 TTY視窗執行完成命令。有以下三種方法:

    1. 通過 命令 expect eof ,表示需要讀取到檔案結束符或到expect 預設時間。
    2. 通過 命令 interact ,在執行完成spawn任務後保持互動狀態,把控制權交給控制檯。這時候可通過手工操作。
    3. 通過 命令 set timeout 10 設定 環境變數 timeout 來保持 spawn等待時間。
# 假如通過SSH登入遠端主機後,拷貝檔案,那麼就需要expect程序等待拷貝完成。
set timeout 10   #第3種方法
spawn rsync -av $file [email protected]$host:$file
#或是 expect eot
# 或是 interact

構建檔案分發系統

  1. 目標是通過spawn遠端登入伺服器,執行rsync命令將本地檔案推送到遠端主機上。
  2. 通過本地shell呼叫expect指令碼,傳遞遠端主機和同步檔案引數。
    #同步指令碼名為ryn.expect .本地shell呼叫。
    # 1遠端主機列表和同步檔案列表。
    cat ../ip.list
    192.168.10.2
    192.168.10.5
    cat ../file.list
    1.txt
    2.txt
    #本地shell指令碼
    cat ../rsync.sh
    #!/bin/bash
    for ip in `cat ip.list`
    do
    echo $ip
        ./ryn.expect $ip list.txt
    done
    # 本地expect同步指令碼
    cat ../ryn.expect
    #!/usr/bin/expect
    set host [lindex $rage 0]
    set filelist [lindex $ragv 1]
    set passwd "123!45"
    spawn rsync -av --files-from=$filelist [email protected]$host:/
    expect{
    "yes/no"{ send "yes\r" }
    "password" { send "$passwd\r" }
    }
    expect eof