一、 rsync 远程同步工具

rsync主要用于备份和镜像。具有速度快、避免复制相同内容和支持符号链接的优点。
rsync和scp区别:用rsync做文件的复制要比scp的速度快,rsync只对差异文件做更新。scp是把所有文件都复制过去。
(1)基本语法
rsync    -rvl       $pdir/$fname              $user@hadoop$host:$pdir/$fname
命令   选项参数   要拷贝的文件路径/名称    目的用户@主机:目的路径/名称
	  选项参数说明
表2-2
选项	   功能
-r	       递归
-v	       显示复制过程
-l	       拷贝符号连接
(2)案例实操
	在HP111机器上的/root/input目录下新建demo2.txt然后同步到HP113服务器的/root/input
	[root@HP111 ~]# rsync -rvl input/ root@HP113:/root/input/
    sending incremental file list
    created directory /root/input
    ./
    demo1.txt
    demo2.txt

    sent 234 bytes  received 91 bytes  650.00 bytes/sec
    total size is 60  speedup is 0.18
    然后在HP113查看

二、编写集群分发脚本xsync

(1)需求:循环复制文件到所有节点的相同目录下
(2)需求分析:
(a)rsync命令原始拷贝:
rsync -rvl /root/software root@HP110:/root/software
(b)期望脚本:
xsync 要同步的文件名称
(c)在/usr/local/bin这个目录下存放的脚本,可以在系统任何地方直接执行。
(3)脚本实现
(a)在/root目录下创建bin目录,并在bin目录下xsync创建文件,文件内容如下:
[root@HP111 ~]# mkdir bin
[root@HP111 ~]# cd bin/
[root@HP111 bin]# touch xsync
[root@HP111 bin]# vi xsync
在该文件中编写如下代码

#!/bin/bash
#1 获取输入参数个数,如果没有参数,直接退出
pcount=$#
if((pcount==0)); then
    echo no args;
    exit;
    fi
        
#2 获取文件名称
p1=$1
fname=`basename $p1`
echo fname=$fname
        
#3 获取上级目录到绝对路径
pdir=`cd -P $(dirname $p1); pwd`
echo pdir=$pdir
        
#4 获取当前用户名称
user=`whoami`
        
#5 循环
for((host=111; host<=113; host++)); do
    echo ------------------- HP$host --------------
    rsync -rvl $pdir/$fname $user@HP$host:$pdir
    done

(b)修改脚本xsync所有用户具有执行权限
[root@HP113 bin]# chmod a+x xsync
(c)调用脚本形式:xsync 文件名称
[root@HP113 bin]# xsync /root/bin
注意:如果将xsync放到/root/bin目录下仍然不能实现全局使用,可以将xsync移动到/usr/local/bin目录下。

(4)调用脚本形式: xcall 操作命令

[root@HP111 ~]# xsync /root/bin
fname=bin
pdir=/root
------------------- HP111 --------------
sending incremental file list

sent 74 bytes  received 17 bytes  60.67 bytes/sec
total size is 532  speedup is 5.85
------------------- HP112 --------------
sending incremental file list
bin/
bin/xsync

sent 652 bytes  received 39 bytes  1,382.00 bytes/sec
total size is 532  speedup is 0.77
------------------- HP113 --------------
sending incremental file list
bin/
bin/xsync

sent 652 bytes  received 39 bytes  1,382.00 bytes/sec
total size is 532  speedup is 0.77

/usr/bin下面的都是系统预装的可执行程序,会随着系统升级而改变。
/usr/local/bin目录是给用户放置自己的可执行程序的地方,推荐放在这里,不会被系统升级而覆盖同名文件。如果两个目录下有相同的可执行程序,这里/usr/local/bin优先于/usr/bin。


三、编写分发脚本xcall

(1)需求分析:在所有主机上同时执行相同的命令
xcall +命令
(2)在/root/bin目录下创建xcall文件,文件内容如下:

#!/bin/bash
pcount=$#
if((pcount==0));then
    echo no args;
    exit;
fi
        
echo -------------start----------
$@
for((host=111; host<=113; host++)); do
    echo ----------HP$host---------
    ssh HP$host $@
done

(3)修改脚本 xcall 所有用户具有执行权限
[root@HP113 bin]# chmod a+x xcall
(4)调用脚本形式: xcall 操作命令

[root@HP111~]# xcall rm -rf /root/input/demo2.txt
[root@HP111 bin]# xcall rm /root/input/demo2.txt 
-------------localhost----------
----------HP111---------
----------HP112---------
----------HP113---------

四、xsync和xcall脚本命令的理解

        这是我自己对xsync和xcall脚本的理解,自己查阅资料总结的,自己以前对shell也不是好,特此记录便于自己理解

获取输入参数个数,如果没有参数,直接退出
pcount=$#          $#表示所有参数的个数 
if((pcount==0)); then   
echo no args;
exit;
fi  
选择语句格式  
if(判断条件)
then 执行语句
fi 结束标志


获取文件名称
p1=$1
fname=`basename $p1`
echo fname=$fname
basename:
[root@HP111 ~]# basename /root/input/demo1.txt 
demo1.txt
为basename指定一个路径,basename命令会将路径信息去除,只留下文件名
p1=$1
fname=`basename $p1` :将xsync命令后面的第一个参数进行basename命令取得文件并复制给fname


获取上级目录到绝对路径
pdir=`cd -P $(dirname $p1); pwd`
echo pdir=$pdir
dirname 用于取指定路径所在的目录 ,如 dirname /root/input/demo1.txt 结果为 /root/input
cd 是去到/root/input
pwd 是取/root/input目录的绝对路径 


获取当前用户名称
user=`whoami`   whoami是Linux操作系统中用于查看当前有效用户名的命令


循环
for((host=111; host<=113; host++)); do
        #echo $pdir/$fname $user@hadoop$host:$pdir
        echo --------------- hadoop$host ----------------
        rsync -rvl $pdir/$fname $user@hadoop$host:$pdir
done
循环语句格式:
for(循环条件)do
	执行语句
done


$@       引用所有参数(命令)
for((host=111; host<=113; host++)); do
        echo ----------hadoop$host---------
        ssh hadoop$host $@   #循环执行引用所有参数(命令)
done
$* 与 $@ 区别:
相同点:都是引用所有参数。
不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。

注意:查看脚本循环条件的主机名是否适合
如:host=111; host<=113; host++循环的主机是不是全部包括集群主机