linux shell + expect:批量scp指令碼工具__linux

來源:互聯網
上載者:User

[轉]http://www.knktc.com/2011/08/20/linux-shell-expect%E6%89%B9%E9%87%8Fscp%E8%84%9A%E6%9C%AC%E5%B7%A5%E5%85%B7/


最近在準備一個部署的任務,其中有一項必須的過程就是將一些檔案,如安裝包發送到大量的伺服器上去。雖然已有宇哥的指令碼可用:通過paramiko模組提供的ssh和scp功能編寫的python指令碼。但我到現在還在對python的恐懼之中(雖然已經在空閑時間努力去學習了),所以我使用了shell和expect指令碼結合的方式,寫了這個批量scp的指令碼工具。

expect用於自動化地執行linux環境下的命令列互動任務,例如scp、ssh之類需要使用者手動輸入密碼然後確認的任務。有了這個工具,定義在scp過程中可能遇到的情況,然後編寫相應的處理語句,就可以自動地完成scp操作了。

需要expect工具的話可以在linux環境中使用apt-get或pacman這些包管理工具去擷取安裝,或是到expect開源項目的網站:http://expect.sourceforge.net/ 來擷取。

安裝expect之後,可以嘗試使用以下的代碼來完成對單個伺服器的scp任務:

 1: #!/usr/bin/expect
 2: 
 3: set timeout 10
 4: set host [lindex $argv 0]
 5: set username [lindex $argv 1]
 6: set password [lindex $argv 2]
 7: set src_file [lindex $argv 3]
 8: set dest_file [lindex $argv 4]
 9: 
 10: spawn scp $src_file $username@$host:$dest_file
 11: expect {
 12:     "(yes/no)?"
 13:         {
 14:             send "yes\n"
 15:             expect "*assword:" { send "$password\n"}
 16:         }
 17:     "*assword:"
 18:         {
 19:             send "$password\n"
 20:         }
 21:     }
 22: expect "100%"
 23: 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指令碼內容如下:

 1: #!/bin/sh
 2: 
 3: list_file=$1
 4: src_file=$2
 5: dest_file=$3
 6: 
 7: cat $list_file | while read line
 8: do
 9:     host_ip=`echo $line | awk '{print $1}'`
 10:     username=`echo $line | awk '{print $2}'`
 11:     password=`echo $line | awk '{print $3}'`
 12:     echo "$host_ip"
 13:     ./expect_scp $host_ip $username $password $src_file $dest_file
 15: done

很簡單的代碼,指定了3個參數:列表檔案的位置、本地源檔案路徑、遠程主機目標檔案路徑。需要說明的是其中的列表檔案指定了遠程主機ip、使用者名稱、密碼,這些資訊需要寫成以下的格式:

IP username password

中間用空格或tab鍵來分隔,多台主機的資訊需要寫多行內容,如:

192.168.75.130 root 123456

192.168.75.131 knktc testpass

這樣就指定了兩台遠程主機的資訊。注意,如果遠程主機密碼中有“$”、“#”這類特殊字元的話,在編寫列表檔案時就需要在這些特殊字元前加上逸出字元,否則expect在執行時會輸入錯誤的密碼。

對於這個shell指令碼,儲存為batch_scp.sh檔案,與剛才儲存的expect_scp檔案和列表檔案(就定義為hosts.list檔案吧)放到同一目錄下,執行時按照以下方式輸入命令就可以了:

./batch_scp.sh ./hosts.list /root/src_file /root/destfile

用這兩個指令檔,就可以簡單地完成批量scp的任務了。

其實批量scp的任務並不難,但是批量ssh的任務可能就會遇到麻煩了。批量ssh的功能正在學習中……(其實已經可以用了但是bug還是很多)

希望這個指令碼能夠幫到大家,謝謝。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.