expect用於自動化地執行linux環境下的命令列互動任務,例如scp、ssh之類需要使用者手動輸入密碼然後確認的任務。有了這個工具,定義在scp過程中可能遇到的情況,然後編寫相應的處理語句,就可以自動地完成scp操作了。
在部署乙個任務時,其中有一項必須的過程就是將一些檔案,如安裝包傳送到大量的伺服器上去。雖然已有宇哥的指令碼可用:通過paramiko模組提供的ssh和scp功能編寫的python指令碼。但我到現在還在對python的恐懼之中(雖然已經在空閒時間努力去學習了),所以使用了shell和expect指令碼結合的方式,寫了這個批量scp的指令碼工具。
expect用於自動化地執行linux環境下的命令列互動任務,例如scp、ssh之類需要使用者手動輸入密碼然後確認的任務。有了這個工具,定義在scp過程中可能遇到的情況,然後編寫相應的處理語句,就可以自動地完成scp操作了。
需要expect工具的話可以在linux環境中使用apt-get或pacman這些包管理工具去獲取安裝,或是到expect開源專案的**: 來獲取。
安裝expect之後,可以嘗試使用以下的**來完成對單個伺服器的scp任務:
#!/usr/bin/expect
set timeout 10
set host [lindex $argv 0]
set username [lindex $argv 1]
set password [lindex $argv 2]
set src_file [lindex $argv 3]
set dest_file [lindex $argv 4]
spawn scp $src_file $username@$host:$dest_file
expect
} "*assword:"
}expect "100%"
expect eof
注意**剛開始的第一行,指定了expect的路徑,與shell指令碼相同,這一句指定了程式在執行時到**去尋找相應的啟動程式。**剛開始還設定了timeout的時間為10秒,如果在執行scp任務時遇到了**中沒有指定的異常,則在等待10秒後該指令碼的執行會自動終止。
從以上**剛開始的幾行可以看出,我為這個指令碼設定了5個需要手動輸入的引數,分別為:目標主機的ip、使用者名稱、密碼、本地檔案路徑、目標主機中的檔案路徑。如果將以上指令碼儲存為expect_scp檔案,則在shell下執行時需要按以下的規範來輸入命令:
./expect_scp 192.168.75.130 root 123456 /root/src_file /root/dest_file
以上的命令執行後,將把本地/root目錄下的src_file檔案拷貝到使用者名為root,密碼為123456的主機192.168.75.130中的/root下,同時還將這個原始檔重新命名為dest_file。
spawn代表在本地終端執行的語句,在該語句開始執行後,expect開始捕獲終端的輸出資訊,然後做出對應的操作。expect**中的捕獲的(yes/no)內容用於完成第一次訪問目標主機時儲存金鑰的操作。有了這一句,scp的任務減少了中斷的情況。**結尾的expect eof與spawn對應,表示捕獲終端輸出資訊的終止。
有了這段expect的**,還只能完成對單個遠端主機的scp任務。如果需要實現批量scp的任務,則需要再寫乙個shell指令碼來呼叫這個expect指令碼。
shell指令碼:
#!/bin/sh
list_file=$1
src_file=$2
dest_file=$3
cat $list_file | while read line
do host_ip=`echo $line | awk ''`
username=`echo $line | awk ''`
password=`echo $line | awk ''`
echo "$host_ip"
./expect_scp $host_ip $username $password $src_file $dest_file
done
指定了3個引數:列表檔案的位置、本地原始檔路徑、遠端主機目標檔案路徑。需要說明的是其中的列表檔案指定了遠端主機ip、使用者名稱、密碼,這些資訊需要寫成以下的格式:
ip username password
中間用空格或tab鍵來分隔,多台主機的資訊需要寫多行內容,如:
192.168.75.130 root 123456
192.168.75.131 jack 654321
這樣就指定了兩台遠端主機的資訊。注意,如果遠端主機密碼中有「$」、「#」這類特殊字元的話,在編寫列表檔案時就需要在這些特殊字元前加上轉義字元,否則expect在執行時會輸入錯誤的密碼。
對於這個shell指令碼,儲存為batch_scp.sh檔案,與剛才儲存的expect_scp檔案和列表檔案(就定義為hosts.list檔案吧)放到同一目錄下,執行時按照以下方式輸入命令就可以了:
./batch_scp.sh ./hosts.list /root/src_file /root/destfile
用這兩個指令碼檔案,就可以簡單地完成批量scp的任務了。
其實批量scp的任務並不難,但是批量ssh的任務可能就會遇到麻煩了。
shell與expect結合使用
摘自 在linux作業系統下,使用指令碼自動化,一般由兩種方案,方案一 telnet ftp,方案二 ssh scp expect。以下主要使用ssh scp expect為例進行說明使用方式。第一步 安裝expect yum y install expect 第二步 驗證,執行expect是否正確...
shell與expect結合使用
在linux作業系統下,使用指令碼自動化,一般由兩種方案,方案一 telnet ftp,方案二 ssh scp expect。以下主要使用ssh scp expect為例進行說明使用方式。第一步 安裝expect yum y install expect 第二步 驗證,執行expect是否正確 第三...
expect和shell的互動
今天寫了個指令碼expect指令碼 本以為很簡單一件事 最後因為expect和shell的一些差別導致浪費了不少時間 特此記錄下 兩者互動時 expect中使用shell命令 注意 shell指令碼太常用了,省略 了shell書寫格式 兩者的變數賦值方式不同 expect中是 set variabl...