日常運維工作中用到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方法最快最方便!!!