一.问题
场景:生产上线,数据备份
有时候我们需要将多个文件远程拷贝到多个服务器
方案:
1.scp命令,将单个文件拷贝到单个服务器方便
2.用ftp的工具,可以一次将多个文件选中拷贝到一台服务器,但是当面临多个文件多个服务器时,也是需要多次执行
那么有什么方法可以一次性就将多个文件拷贝到多个服务器呢.
二.命令
sscp命令
命令的脚本我放在最后了,先看使用的效果
1.帮助文档
命令:
sscp -h
结果
作用: 用于远程拷贝文件(可试用于多个文件,多个服务器)
用法: sscp [选项]
-s 源文件或文件夹(文件夹下所有的文件将会拷贝)
-d 目标服务器ip或(服务器信息文件)
-l 目标服务器路径
-n 单个目标服务器的用户名
-p 单个目标服务器的密码
-S 在当前目录生成目标服务器信息文件
-h 帮助文档
示例:
1.拷贝单个文件到单个服务器:
sscp -s a.txt -d 192.168.9.100 -l /data/ -n root -p 123456
2.生产服务器信息文件:格式(ip 路径 用户名 密码)
sscp -S
3.拷贝多个文件到多个服务器:
sscp -s /test/ -d ./destServer.txt
2.单个文件拷贝到单个服务器
命令:
sscp -s a.txt -d 192.168.9.101 -l /data/ -n root -p
结果:(这里密码我没有在命令中指定,而是隐性输入的,包括ip,路径,用户名都可以隐形输入)
服务器密码:
等待传输......
=======================开始===================
a.txt------------------>192.168.9.101 OK!
传输完成!---总共:01条记录---成功:01条记录---失败:0条记录---!
日志路径:/tmp/sscp.log
=======================结束===================
这里,大家会发现,这条命令虽然能远程拷贝,但是我为什么不直接用scp呢,scp还简单些!
确实:如果是单个文件到单个服务器,真没必要用这个命令
3.生成服务器信息文件
命令:
sscp -S
结果:
文件生成完成!!!
会发现在当前目录,生成了一个 destServer.txt 的文件,文件内容
192.168.9.100 /data/ root abc123456
192.168.9.101 /data/ root abc123456
服务器ip 服务器路径 用户名 密码
4.多个文件到多个服务器
命令:
test/为目录.目录下面有多个文件b.txt,c.txt
destServer.txt保存着我们要传输服务器的信息
sscp -s test/ -d destServer.txt
结果:
=======================开始===================
test/b.txt------------------>192.168.9.100 OK!
test/b.txt------------------>192.168.9.101 OK!
test/c.txt------------------>192.168.9.100 OK!
test/c.txt------------------>192.168.9.101 OK!
传输完成!---总共:4条记录---成功:4条记录---失败:0条记录---!
日志路径:/tmp/sscp.log
=======================结束===================
这时候我们,去服务器上查看,会发现两个文件均传到两个服务器了.
两个服务器不算多,当如果我们有几十个上百个服务器需要相同的文件时,我们也只需要将服务器的信息保存在服务器信息文件中即可.
当然:如果单个文件到多个服务器,多个文件到单个服务器,都是可以通过该命令一条完成.这大大节约了我们的文件传输操作步骤.
当然一个非常完善的系统,可能早就已经有各种自动化工具进行部署,但是当面临新的系统时,总避免不了手动去传输.
三.创建命令
1.
cd /usr/local/bin/
2.
vim sscp
#!/bin/bash
#帮助文档
function help(){
echo "作用: 用于远程拷贝文件(可试用于多个文件,多个服务器)"
echo "用法: sscp [选项]"
echo ""
echo " -s 源文件或文件夹(文件夹下所有的文件将会拷贝)"
echo " -d 目标服务器ip或(服务器信息文件)"
echo " -l 目标服务器路径"
echo " -n 单个目标服务器的用户名"
echo " -p 单个目标服务器的密码"
echo " -S 在当前目录生成目标服务器信息文件"
echo " -h 帮助文档"
echo ""
echo "示例:"
echo "1.拷贝单个文件到单个服务器:"
echo " sscp -s a.txt -d 192.168.9.100 -l /data/ -n root -p 123456"
echo ""
echo "2.生产服务器信息文件:格式(ip 路径 用户名 密码)"
echo " sscp -S"
echo ""
echo "3.拷贝多个文件到多个服务器:"
echo " sscp -s /data/ -d ./destServer.txt"
exit 1
}
#目标服务器信息文件生成
function destServerFile(){
if [[ -f destServer.txt ]]; then
rm -f destServer.txt
fi
touch destServer.txt
echo "192.168.9.100 /data/ root abc123456" >> destServer.txt
echo "192.168.9.101 /data/ root abc123456" >> destServer.txt
echo "文件生成完成!!!"
exit 0
}
#参数检查
function argVolidate(){
#参数个数为0个,直接输出帮助文档
if [[ $# == 0 ]] || [[ $# -gt 10 ]]; then
echo "[error]:参数错误!!!"
help
fi
#参数为-h
if [[ $# == 1 ]] && [[ $1 == "-h" ]]; then
help
fi
#参数个数为1个,则参数必须为-S,-h,--help
if [[ $# == 1 ]]; then
if [[ $1 != "-S" ]]; then
echo "[error]:参数错误!!!"
help
else
destServerFile
fi
fi
#参数个数为2及2个以上,则参数只能为-s,-d,-n,-p,且参数不大于8个
argIndex=0
for arg in $*
do
let argIndex+=1
argNum=$((argIndex%2))
if [[ $argNum != 0 ]] && [[ $arg != "-s" ]] && [[ $arg != "-d" ]] && [[ $arg != "-l" ]] && [[ $arg != "-n" ]] && [[ $arg != "-p" ]]; then
echo "[error]:参数错误!!!"
help
fi
done
}
#数据解析
function parse(){
argIndex=0
argValue=""
for arg in $*
do
let argIndex+=1
argNum=$((argIndex%2))
case $argValue in
"-s")
src=$arg
;;
"-d")
dest=$arg
;;
"-l")
destDir=$arg
;;
"-n")
name=$arg
;;
"-p")
password=$arg
;;
*)
argvalue=""
;;
esac
argValue=""
if [[ $argNum != 0 ]]; then
if [[ $arg == "-s" ]] || [[ $arg == "-d" ]] || [[ $arg == "-l" ]] || [[ $arg == "-n" ]] || [[ $arg == "-p" ]]; then
argValue=$arg
fi
fi
done
}
#检查用户需要输入的信息
function inputVolidate(){
if [[ $dest == "" ]]; then
echo "请输入目标服务器ip:"
read dest
fi
if [[ ! -f $dest ]]; then
if [[ $destDir == "" ]]; then
echo "服务器路径:"
read destDir
fi
if [[ $name == "" ]]; then
echo "服务器用户名:"
read name
fi
if [[ $password == "" ]]; then
echo "服务器密码:"
read -s password
echo "等待传输......"
fi
fi
}
#传输方法
#参数:第一个:源文件,第二个:目标服务器用户名,第三个:目标服务器ip,第四个:目标服务器地址,第五个目标服务器密码
function scpStreng(){
sshpass -p $5 scp -p $1 $2@$3:$4 >/tmp/sscp.log 2>&1
result=$?
if [[ $result == 0 ]]; then
echo "$1------------------>$3 OK!"
let success=$success+1
else
echo "$1------------------>$3 fail!"
let faild=$faild+1
fi
let total=$faild+1
}
#单个文件传输
#参数:第一个:源文件,第二个:用户输入的服务器用户名,第三个:目标服务器ip,第四个:目标服务器地址,第五个目标服务器密码
function singelFile(){
if [[ $name != "" ]]; then
echo "直接chuansh"
scpStreng $src $name $dest $destDir $password
else
hosts=$(awk 'END{print NR}' $dest)
i=1
while [[ i -le $hosts ]]
do
hostIp=$(sed -${i} $dest |awk -F ' ' '{print $1}')
hostDir=$(sed -${i} $dest |awk -F ' ' '{print $2')
hostName=$(sed -${i} $dest |awk -F ' ' '{print $3}')
hostPassword=$(sed -${i} $dest |awk -F ' ' '{print $4}')
scpStreng $src $hostName $hostIp $hostDir $hostPassword
let i+=1
done
fi
}
argVolidate $*
#全局变量
src=""
dest=""
destDir=""
name=""
password=""
total=0
faild=0
success=0
parse $*
echo "$name"
inputVolidate
#传输开始
echo "=======================开始==================="
if [[ -f $src ]]; then
if [[ $name != "" ]]; then
scpStreng $src $name $dest $destDir $password
else
hosts=$(awk 'END{print NR}' $dest)
i=1
while [[ i -le $hosts ]]
do
hostIp=$(sed -n ${i}p $dest |cut -f 1 -d ' ')
hostDir=$(sed -n ${i}p $dest |cut -f 2 -d ' ')
hostName=$(sed -n ${i}p $dest |cut -f 3 -d ' ')
hostPassword=$(sed -n ${i}p $dest |cut -f 4 -d ' ')
scpStreng $src $hostName $hostIp $hostDir $hostPassword
let i+=1
done
fi
else
for file in `ls $src`
do
nowSrc=$src$file
if [[ $name != "" ]]; then
scpStreng $nowSrc $name $dest $destDir $password
else
hosts=$(awk 'END{print NR}' $dest)
i=1
while [[ i -le $hosts ]]
do
hostIp=$(sed -n ${i}p $dest |cut -f 1 -d ' ')
hostDir=$(sed -n ${i}p $dest |cut -f 2 -d ' ')
hostName=$(sed -n ${i}p $dest |cut -f 3 -d ' ')
hostPassword=$(sed -n ${i}p $dest |cut -f 4 -d ' ')
scpStreng $nowSrc $hostName $hostIp $hostDir $hostPassword
let i+=1
done
fi
done
fi
#传输完成
echo "传输完成!---总共:${total}条记录---成功:${success}条记录---失败:${faild}条记录---!"
echo "日志路径:/tmp/sscp.log"
echo "=======================结束==================="
3.
chmod 755 sscp
4.
接下来就可以使用了