日常运维工作中用到rsync同步两个目录时,有时会要求删除目标目录中比源目录多出的文件,这种情况下,可用到rsync的--delete参数来实现。
实例说明:
在服务器A上同步/tmp/work目录到远程服务器B的/tmp/work目录下(A和B已经提前做好ssh无密码信任跳转关系了),同时删除B服务器/tmp/work目录下相比于A服务器/tmp/work中多余的文件
最近在处理策划资源文件的时候需要将目录A的文件全部同步到目录B的文件,并且把目录B内多余的文件全部删除掉。所以,就想到了使用rsync的--delete参数来实现功能。
1)A服务器
[root@serverA ~]# cd /tmp/work
[root@serverA work]# ls
a b c d 11
2)B服务器
[root@serverB ~]# cd /tmp/work
[root@serverB work]# ls
c d 11 12 13 fg 5t
3)从A服务器同步到B服务器(假设B服务器ip是11.11.11.11)
[root@serverA work]# rsync -e "ssh -p22" -avpz --delete ./ root@11.11.11.11:/tmp/work/ #注意,--delete参数要放在源目录和目标目录前,并且两个目录结构一定要一致!不能使用./*
sending incremental file list
./
deleting fg
deleting 5t
deleting 13
deleting 12
11
a
b
c
d
sent 248 bytes received 110 bytes 716.00 bytes/sec
total size is 0 speedup is 0.00
4)再次查看B服务器,发现已经跟A服务器的/tmp/work目录同步了,并且删除了多余的文件
[root@serverB ~]# cd /tmp/work
[root@serverB work]# ls
a b c d 11
********************************************************************************
扩展:
下面根据示例说明几个用法:
$ mkdir {dirA,dirB} //创建两个测试目录
//分别在两个目录创建相应的文件
$ touch dirA/{fileA1.txt,fileA2.txt,fileA3.txt}
$ touch dirB/{fileA1.txt,fileA2.txt,fileA3.txt,fileB1.txt,fileB2.txt,fileB3.txt}
1)将dirA的所有文件同步到dirB内,并保留文件的属主,属组,文件权限等信息。
$ rsync -avz dirA/ dirB/
sending incremental file list
./
fileA1.txt
fileA2.txt
fileA3.txt
sent 199 bytes received 72 bytes 542.00 bytes/sec
total size is 0 speedup is 0.00
2)将dirA的所有文件同步到dirB内,并删除dirB内多余的文件
$ rsync -avz --delete dirA/ dirB/ #源目录和目标目录结构一定要一致!!不能是dirA/* dirB/ 或者dirA/ dirB/* 或者 dirA/* dirB/*
sending incremental file list
./
deleting fileB3.txt
deleting fileB2.txt
deleting fileB1.txt
fileA1.txt
fileA2.txt
fileA3.txt
sent 203 bytes received 72 bytes 550.00 bytes/sec
total size is 0 speedup is 0.00
3)将dirA的所有文件同步到dirB,但是在dirB内除了fileB3.txt这个文件不删之外,其他的都删除。
$ rsync -avz --delete --exclude "fileB3.txt" dirA/ dirB/
sending incremental file list
./
deleting fileB2.txt
deleting fileB1.txt
fileA1.txt
fileA2.txt
fileA3.txt
sent 203 bytes received 72 bytes 550.00 bytes/sec
total size is 0 speedup is 0.00
4)将dirA目录内的fileA1.txt和fileA2.txt不同步到dirB目录内。
$ rsync -avz --exclude="fileA1.txt" --exclude="fileA2.txt" dirA/ dirB/
sending incremental file list
fileA3.txt
sent 106 bytes received 31 bytes 274.00 bytes/sec
total size is 0 speedup is 0.00
5) 将dirA目录内的fileA1.txt和fileA2.txt不同步到dirB目录内,并且在dirB目录内删除多余的文件。
$ rsync -avz --exclude="fileA1.txt" --exclude="fileA2.txt" --delete dirA/ dirB/
sending incremental file list
deleting fileB3.txt
deleting fileB2.txt
deleting fileB1.txt
fileA3.txt
sent 106 bytes received 31 bytes 274.00 bytes/sec
total size is 0 speedup is 0.00
6)将dirA目录内的fileA1.txt和fileA2.txt不同步到dirB目录内,并且在dirB目录内删除多余的文件,同时,如果dirB内有fileA2.txt和fileA1.txt这两个被排除同步的文件,仍然将其删除。
$ rsync -avz --exclude="fileA1.txt" --exclude="fileA2.txt" --delete-excluded dirA/ dirB/
sending incremental file list
./
deleting fileB3.txt
deleting fileB2.txt
deleting fileB1.txt
deleting fileA2.txt
deleting fileA1.txt
fileA3.txt
sent 109 bytes received 34 bytes 286.00 bytes/sec
total size is 0 speedup is 0.00
这里可以看到只有fileA3.txt被同步到dirB目录内,同时dirB目录内的fileA1.txt和fileA2.txt两个被过滤的文件也被删除掉了。
####################################################################
#################### Rsync替换原理,快速删除海量文件 ###########################
####################################################################
要在Linux下删除海量文件的情况,需要删除数十万个文件。这个是之前的程序写的日志,增长很快,而且没什么用。这个时候常用的删除命令rm -fr * 就不好用了,因为要等待的时间太长。所以必须要采取一些非常手段:可以使用rsync的--delete-before参数来实现快速删除大量文件。
1)建立一个空的文件夹:
# mkdir /tmp/test
2)用rsync删除目标目录:
# rsync --delete-before -a -H -v --progress --stats /tmp/test/ log/
这样要删除的log目录就会被清空了,删除的速度会非常快。rsync实际上用的是替换原理,处理数十万个文件也是秒删。
选项说明:
--delete-before 接收者在传输之前进行删除操作
--progress 在传输时显示传输过程
--a 归档模式,表示以递归方式传输文件,并保持所有文件属性
--H 保持硬连接的文件
--v 详细输出模式
--stats 给出某些文件的传输状态
###############################################################
################ Linux下删除大量文件的几种方法的效率对比 ######################
###############################################################
在Liunx系统下对于大量文件的删除有很多中方法,如rm、find、rsync、python删除等。下面通过测试案例对比出集中删除方法的效率。
为了测试效果,这里首先创建50万个文件:
[root@localhost ~]# mkdir test [root@localhost ~]# cd test [root@localhost test]# for file in $(seq 1 500000).log;do echo "this is test" >> ${file}.log;done [root@localhost test]# ls 17480.log 24981.log 32481.log 39983.log 47483.log 54984.log 62484.log 69986.log 77486.log 84987.log 92487.log 99989.log 17481.log 24982.log 32482.log 39984.log 47484.log 54985.log 62485.log 69987.log 77487.log 84988.log 92488.log 9998.log 17482.log 24983.log 32483.log 39985.log 47485.log 54986.log 62486.log 69988.log 77488.log 84989.log 92489.log 99990.log 17483.log 24984.log 32484.log 39986.log 47486.log 54987.log 62487.log 69989.log 77489.log 8498.log 9248.log 99991.log ......... ......... [root@localhost test]# du -sh /root/test 395M /root/test
1. rm方法删除 [由于文件数量过多,rm删除不起作用!原因是文件夹下的文件数目过多,命令行过长所致]
[root@localhost ~]# rm -f /root/test/*.log -bash: /usr/bin/rm: Argument list too long 尝试切换到删除的目标目录下进行删除,rm命令中不要跟绝对路径,直接在当前目录下删除! [root@localhost ~]# cd /root/test/ [root@localhost test]# time rm -f *.log -bash: /usr/bin/rm: Argument list too long ....... 如果还是出现"-bash: /usr/bin/rm: Argument list too long"报错,还可以尝试结合xargs命令来删除! [root@localhost ~]# cd /root/test/ [root@localhost test]# ls *.log|xargs -n10 rm -f -bash: /usr/bin/rm: Argument list too long [root@localhost test]# ls * |xargs -n 10 rm -f #当文件量过多时,最好是切换到目标目录下,直接删除*,不跟跟全路径! -bash: /usr/bin/ls: Argument list too long 上面命令的解释: 输出所有的文件名(用空格分割) xargs就是将ls的输出,每10个为一组(以空格为分隔符。"-n 10" 和 "-n10"是一个意思), 作为rm -rf的参数也就是说将所有文件名10个为一组,由rm -rf删除,这样就不会超过命令行的长度了。 使用for循环进行rm删除也不行! [root@localhost test]# for i in `ls /root/test/*.log`;do rm -f $i;done -bash: /usr/bin/ls: Argument list too long [root@localhost test]# for i in `ls /root/test/*`;do rm -f $i;done -bash: /usr/bin/ls: Argument list too long [root@localhost test]# for i in `ls *`;do rm -f $i;done -bash: /usr/bin/ls: Argument list too long
2. find + rm 命令删除 [耗时40多分钟!]
[root@localhost test]# time find /root/test -type f -name *.log -exec rm -f {} ; -bash: /usr/bin/find: Argument list too long real 0m1.303s user 0m1.159s sys 0m0.143s 当文件量过多时,不跟要全路径删除,直接切换到目标目录下删除! [root@localhost test]# cd /root/test/ [root@localhost test]# time find ./ -type f -exec rm -f {} ; 这样就可以删除了,但是find命令很耗时,用了40多分钟!!!
3. find + delete 命令删除 [耗时9分钟]
[root@localhost test]# time find ./ -type f -delete
4. rsync删除 [耗时18秒,很强大]
首先建立空文件夹empty [root@localhost ~]# mkdir /root/empty 然后使用rsync替换原理进行空覆盖!快速删除功能很强大!! [root@localhost ~]# time rsync -avpgolr --delete /root/empty/ /root/test/
结论:对于海量小文件的删除,find方法最慢,rsync方法最快最方便!!!