bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.htmlhtml
expect工具能夠實現自動應答,從而達到非交互的目的。shell
expect具體使用用法比較複雜,中文手冊我正在翻譯中,之後翻譯完了作了整理再補。本文只有幾個ssh相關最可能用上的示例。bash
yum -y install expect
如下是scp自動問答的腳本。ssh
[root@xuexi ~]# cat autoscp.exp #!/usr/bin/expect
########################################################### # description: scp without interactive # # author : 駿馬金龍 # # blog : http://www.cnblogs.com/f-ck-need-u/ # ########################################################### set timeout 10 set user_hostname [lindex $argv 0] set src_file [lindex $argv 1] set dest_file [lindex $argv 2] set password [lindex $argv 3] spawn scp $src_file $user_hostname:$dest_file expect { "(yes/no)?" { send "yes\n" expect "*assword:" { send "$password\n"} } "*assword:" { send "$password\n" } } expect "100%" expect eof
用法:autoscp.exp [user@]hostname src_file dest_file [password]工具
該自動回答腳本能夠自動完成主機驗證和密碼認證,即便已是實現公鑰認證的機器也沒問題,由於公鑰認證機制默認優先於密碼認證,且此腳本的password項是可選的,固然,在沒有實現公鑰認證的狀況下,password是必須項,不然expect實現非交互的目的就失去意義了。spa
如下是幾個示例:翻譯
[root@xuexi ~]# ./autoscp.exp 172.16.10.6 /etc/fstab /tmp 123456 spawn scp /etc/fstab 172.16.10.6:/tmp The authenticity of host '172.16.10.6 (172.16.10.6)' can't be established. RSA key fingerprint is f3:f8:e2:33:b4:b1:92:0d:5b:95:3b:97:d9:3a:f0:cf. Are you sure you want to continue connecting (yes/no)? yes # 主機驗證時詢問是否保存host key,自動回答yes Warning: Permanently added '172.16.10.6' (RSA) to the list of known hosts. root@172.16.10.6's password: # 密碼認證過程,自動回答指定的密碼"123456" fstab 100% 805 0.8KB/s 00:00
也能夠指定完成的用戶名和主機名。code
[root@xuexi ~]# ./autoscp.exp root@172.16.10.6 /etc/fstab /tmp 123456 spawn scp /etc/fstab root@172.16.10.6:/tmp root@172.16.10.6's password: fstab 100% 805 0.8KB/s 00:00
如下是在創建公鑰認證機制時,ssh-copy-id拷貝公鑰到服務端的自動應答腳本。htm
[root@xuexi ~]# cat /tmp/autocopy.exp #!/usr/bin/expect ########################################################### # description: scp without interactive # # author : 駿馬金龍 # # blog : http://www.cnblogs.com/f-ck-need-u/ # ########################################################### set timeout 10 set user_hostname [lindex $argv 0] set password [lindex $argv 1] spawn ssh-copy-id $user_hostname expect { "(yes/no)?" { send "yes\n" expect "*assword:" { send "$password\n"} } "*assword:" { send "$password\n" } } expect eof
用法:autocopy.exp [user@]hostname passwordblog
如下是一個示例,
[root@xuexi ~]# /tmp/autocopy.exp root@172.16.10.6 123456 spawn ssh-copy-id root@172.16.10.6 The authenticity of host '172.16.10.6 (172.16.10.6)' can't be established. RSA key fingerprint is f3:f8:e2:33:b4:b1:92:0d:5b:95:3b:97:d9:3a:f0:cf. Are you sure you want to continue connecting (yes/no)? yes # 主機認證時,自動應答yes Warning: Permanently added '172.16.10.6' (RSA) to the list of known hosts. root@172.16.10.6's password: # 密碼認證時自動輸入密碼"123456" Now try logging into the machine, with "ssh 'root@172.16.10.6'", and check in: .ssh/authorized_keys to make sure we haven't added extra keys that you weren't expecting.
若是要實現批量非交互,則能夠寫一個shell腳本調用該expect腳本。例如:
[root@xuexi ~]# cat /tmp/sci.sh #!/bin/bash ########################################################### # description: scp without interactive # # author : 駿馬金龍 # # blog : http://www.cnblogs.com/f-ck-need-u/ # ########################################################### passwd=123456 # 指定要傳遞的密碼爲123456 user_host=`awk '{print $3}' ~/.ssh/id_rsa.pub` # 此變量用於判斷遠程主機中是否已添加本機信息成功 for i in $@ do /tmp/autocopy.exp $i $passwd >&/dev/null ssh $i "grep "$user_host" ~/.ssh/authorized_keys" >&/dev/null # 判斷是否添加本機信息成功 if [ $? -eq 0 ];then echo "$i is ok" else echo "$i is not ok" fi done
用法:/tmp/sci.sh [user@]hostname
其中hostname部分能夠使用花括號展開方式枚舉。但有個bug,最好ssh-copy-id的目標不要是腳本所在的本機,可能會強制輸入本機密碼,但批量腳本autocopy.exp則沒有此bug。
例如:
[root@xuexi tmp]# /tmp/sci.sh 172.16.10.3 172.16.10.6 172.16.10.3 is ok 172.16.10.6 is ok
[root@xuexi tmp]# /tmp/sci.sh 172.16.10.{3,6} 172.16.10.3 is ok 172.16.10.6 is ok
[root@xuexi tmp]# /tmp/sci.sh root@172.16.10.3 172.16.10.6 root@172.16.10.3 is ok 172.16.10.6 is ok