| 关键词: nbsp file ssh scp exit expect default 文件 程序 批量 |
对之前的版本进行升级,增加支持密码从命令行输入方式,增加提示那些机器上传成功或者失败提示。 对于运维来说,同时管理多台机器是很辛苦的事情,特别是CDN运维需要上传一个文件到1000台机器的话,靠人工一个个上传非常费劲,为此我写了一个批量scp文件到多台机器上的小程序。其中用到了expect: Expect在这个程序里就是用来帮助自动输入scp的密码,Expect主要用于把需要人工交互的程序变为程序自动化完成,这个对于运维批量部署系统,批量无人值守安装,批量执行命令,批量上传下载 现代的Shell对程序提供了最小限度的控制(开始,停止,等等),而把交互的特性留给了用户。 这意味着有些程序,你不能非交互的运行,比如说passwd。 有一些程序可以非交互的运行,但在很大程度上丧失了灵活性,比如说fsck。这表明Unix的工具构造逻辑开始出现问题。Expect恰恰填补了其中的一些裂痕,解决了在Unix环境中长期存在着的一些问题。 Expect使用Tcl作为语言核心。不仅如此,不管程序是交互和还是非交互的,Expect都能运用。 1.multi_scp_upload.sh的源代码 #!/bin/bash #author: yifangyou #create time:2011-05-17 #用来通过scp批量上传文件或者目录到目标机器的指定目录 #配置文件格式: #ssh_hosts=("1.1.1.1" "2.2.2.2") #ssh_ports=("22" "22") 这个可以缺省,缺省值为22,或者个数比ssh_hosts少时,使用缺省值 #ssh_users=("root" "root") 这个可以缺省,缺省值为root,,或者个数比ssh_hosts少时,使用缺省值 #ssh_passwords=("323" "222") 这个可以缺省,缺省的话需要从命令行输入,或者个数比ssh_hosts少时,使用命令行输入 #执行:sh multi_scp.sh conf_file_path file target if [ -z "$3" ] then echo "sh multi_scp.sh conf_file_path file target"; exit; fi default_ssh_user="root" default_ssh_port="22"; #upload shell script file path scp_upload=scp_upload.sh #configure file path conf_file=$1 #then upload file path scp_file=$2 #remote host'target file or dir path scp_target=$3 #判断conf_file配置文件是存在 if [ ! -e "$conf_file" ] then echo "$conf_file is not exists"; exit; fi #判断scp_file是文件或者目录 if [ ! -e "$scp_file" ] && [ ! -d "$scp_file" ] then echo "$scp_file is not exists"; exit; fi #read configure file source $conf_file #若是没有在配置文件里提供密码,则在命令行输入 if [ "${#ssh_passwords[@]}" = "0" ] || [ "${#ssh_passwords[@]}" -lt "${#ssh_hosts[@]}" ] then read -p "please input password:" -s default_ssh_password fi success_hosts=""; fail_hosts=""; for((i=0;i<${#ssh_hosts[@]};i++)) do #remote ssh host ssh_host=${ssh_hosts[$i]}; #remote ssh port ssh_port=${ssh_ports[$i]}; if [ "$ssh_port" = "" ] then ssh_port=$default_ssh_port; fi #remote ssh user ssh_user=${ssh_users[$i]}; if [ "$ssh_user" = "" ] then ssh_user=$default_ssh_user; fi #remote ssh password ssh_password=${ssh_passwords[$i]}; if [ "$ssh_password" = "" ] then ssh_password=$default_ssh_password; fi echo "["`date +"%F %T"`"] (scp -r $scp_file $ssh_user@$ssh_host:$ssh_port:$scp_target) start" #scp file or dir /usr/bin/expect scp_upload.sh "$ssh_host" "$ssh_port" "$ssh_user" "$ssh_password" "$scp_file" "$scp_target" if [ "$?" -eq "0" ] then success_hosts="$success_hosts,$ssh_host" else fail_hosts="$fail_hosts,$ssh_host" fi echo "["`date +"%F %T"`"] (scp -r $scp_file $ssh_user@$ssh_host:$ssh_port:$scp_target) end" echo "" done echo "success_hosts=[$success_hosts]" echo "fail_hosts=[$fail_hosts]" 2.scp_upload.sh的源代码 #!/usr/bin/expect #author: yifangyou #create time:2011-05-17 #host set scphost "[lindex $argv 0]" #ssh端口 set port "[lindex $argv 1]" #ssh用户名 set scpuser "[lindex $argv 2]" #ssh密码 set scppw "[lindex $argv 3]" #要上传的文件名或者目录 set file "[lindex $argv 4]" #要上传到远程机器的文件名或者目录 set target "[lindex $argv 5]" spawn scp -r -P $port $file $scpuser@$scphost:$target #设置超时时间,防止远程机器防火墙没有开,而挂起 set timeout 30 expect { #respose: "[email protected]'s password:",自动输入密码 "*password*" { set timeout 30 send "$scppw " } #the first connect will respose "Are you sure you want to continue connecting (yes/no)? yes" "*yes*" { set timeout 30 send "yes " set timeout 30 expect "*password*" set timeout 30 send "$scppw " } busy {send_user " <error:busy>";exit 1;} failed {send_user " <error:failed>";exit 2;} timeout {send_user " <error:timeout>";exit 3;} } #Permission denied not try again,回报出错信息 set timeout 30 expect { "*denied*" { send_user " <error:Permission denied>" exit 4 } "*No such file*" { send_user " <error:No such file>" exit 5 } busy {send_user " <error:busy>";exit 6;} failed {send_user " <error:failed>";exit 7;} timeout {send_user " <error:timeout>";exit 8;} } exit 0 3.配置文件格式scp.conf #ssh_hosts=("1.1.1.1" "2.2.2.2") #ssh_ports=("22" "22") #wheen port_num < host_num use default=22,or ssh_ports is undefined use 22 as default value #ssh_users=("root" "root") #wheen user_num < host_num use default=root,or ssh_users is undefined use root as default value #ssh_passwords=("323" "222") #wheen password_num < host_num use default=input password,or ssh_users is undefined use input password 4.运行代码 找一台机器可以和要上传的机器联通,安装好expect(可以用expect命令测试是否已经安装过了) 把scp_upload.sh,multi_scp_upload.sh,scp.conf放到同一个目录下,运行multi_scp_upload.sh即可 5.运行效果 |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|