rsync基礎

来源:https://www.cnblogs.com/alongdidi/archive/2019/01/08/rsync.html
-Advertisement-
Play Games

參考資料:駿馬金龍的rsync系列。該博主的博文質量很好,推薦大家關註。 環境 操作系統:CentOS Linux release 7.5.1804 (Core) 軟體:rsync version 3.1.2 protocol version 31 前言 rsync可以實現scp的部分遠程複製功能( ...


參考資料:駿馬金龍的rsync系列。該博主的博文質量很好,推薦大家關註。

環境

操作系統:CentOS Linux release 7.5.1804 (Core)

軟體:rsync  version 3.1.2  protocol version 31

 

前言

rsync可以實現scp的部分遠程複製功能(支持本地到遠程複製和遠程到本地複製,但是不支持遠程到遠程複製;scp可以支持遠程到遠程複製)、cp的本地複製功能、rm的刪除功能和“ls -l”的顯示詳細信息文件列表功能。

註意,rsync的初衷是實現兩端主機之間的數據同步,上述功能只是作為輔助,並且其實現方式是與scp/cp/rm/ls這些命令不同的。

rsync有自己的一套演算法以及演算法實現機制,日常使用的話可以無需瞭解。但是,如果想要看懂rsync的man手冊或者官方文檔,想要通過-vvvv選項看懂rsync的執行過程,那麼還是有必要瞭解rsync的原理的。

 

同步基礎

同步涉及到了源文件(源主機、發送端)和目標文件(目標主機、接收端)、本地主機和遠程主機、以及以哪邊的主機上的文件為基準的概念。以誰為基準,就是以誰作為源文件。

  • 想讓本地主機上的文件和遠程主機上的文件保持同步。則以遠程主機上的文件為基準(即作為源文件),將其拉取到本地主機覆蓋本地主機的文件(即作為目標文件)。
  • 想讓遠程主機上的文件和本地主機上的文件保持同步。則以本地主機上的文件為基準(即作為源文件),將其推送到遠程主機覆蓋遠程主機的文件(即作為目標文件)。
  • 本地主機和遠程主機,既可以作為源主機/發送端,也可以作為目標主機/接收端,看具體的情況而定。

同步的過程,還涉及到其他的問題。

  • 是否刪除源主機上沒有但是目標主機上多出來的文件?
  • 目標文件的mtime比源文件的mtime更(gèng)新的時候,是否覆蓋?
  • 遇到字元鏈接時,是同步字元鏈接本身還是其所指向的文件?即是否追蹤字元鏈接文件?
  • 目標文件已存在時,是否做備份?
  • 等等其他情況。

上面這些操作,都是需要rsync來完成的,這也就是為什麼在使用rsync的時候要求源和目標主機都需要安裝有rsync程式包。

rsync的同步由檢查模式和同步模式兩部分構成。

檢查模式

檢查模式用於檢查哪些文件應該被同步,哪些文件不應該被同步。比如--exclude選項排除了不應該被同步的文件。預設情況下,rsync使用quick check演算法來檢查源文件和目標文件的size(文件大小)與mtime。當size或者mtime不同的時候,就會判定文件應該被同步。

可以通過一些選項來修改檢查模式,例如--size-only用於指明將僅檢查文件的size而不檢查mtime。

還有其他的選項也可以用於修改檢查模式,彈性十足。

同步模式

同步模式用於處理上面所說的“是否刪除本地主機上沒有但是遠程主機上多出來的文件?”之類的問題。同步模式也有許多選項可以指定,也是彈性十足。

一般情況下我們是修改同步模式,少數情況下才會修改檢查模式,因為後者的修改容易引起性能的較大改動(例如--checksum)或者沒有正確同步應該同步的文件(例如--size-only)。

 

三種工作方式

rsync有三種工作方式,即三種語法格式,如下。

Local:  rsync [OPTION...] SRC... [DEST]

Access via remote shell:
 Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]
 Push: rsync [OPTION...] SRC... [USER@]HOST:DEST

Access via rsync daemon:
 Pull: rsync [OPTION...] [USER@]HOST::SRC... [DEST]
       rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]
 Push: rsync [OPTION...] SRC... [USER@]HOST::DEST
       rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST
  1. 第一種方式是上述的Local部分,為本地主機內部的同步。
  2. 第二種方式是上述的remote shell部分,為不同主機通過遠程shell實現同步。
  3. 第三種方式是上述的rsync daemon部分,為不同主機通過網路套接字實現同步。這種方式在指定daemon的時候有兩種形式。有雙冒號形式和URL形式,都是可以的,個人傾向於URL形式,比較不會和單冒號形式相似。前面演示的示例都是本地主機或者遠程shell,最後再單獨講rsync daemon方式。

前兩者的本質是基於管道;第三種是需要先在遠程主機上運行一個daemon,監聽在某個埠上,然後本地主機通過網路套接字與其通信。

還有一種特殊的方式,是基於遠程shell連接上之後,在遠程主機上臨時運行一個daemon,當數據同步完畢後,daemon也會結束。這種方式的命令行語法類似rsync daemon模式,不同的點在於選項需要指明-e或者--rsh。

本文中我們將其稱為“臨時daemon”,註意,這隻是個人對其稱呼,非官方。

命令的參數可以有多個;當指定多個的時候,只有最後一個表示目標文件,其餘都為源文件,目標文件若不存在則自動創建為目錄,若存在則必須得是目錄,否則報錯。

[root@C7 ~]# file /tmp/1.txt 
/tmp/1.txt: empty
[root@C7 ~]# rsync /etc/fstab /etc/inittab /tmp/1.txt
ERROR: destination must be a directory when copying more than 1 file
rsync error: errors selecting input/output files, dirs (code 3) at main.c(623) [Receiver=3.1.2]

如果參數只有一個SRC的話,那麼等同於“ls -l”。

[root@c7-client ~]# rsync /etc/fstab 
-rw-r--r--            487 2018/12/18 11:46:20 fstab
[root@c7-client ~]# rsync /etc/ssh/
drwxr-xr-x            225 2018/12/18 12:04:37 .
-rw-r--r--        581,843 2018/04/11 12:21:29 moduli
-rw-r--r--          2,276 2018/04/11 12:21:29 ssh_config
-rw-r-----            227 2018/12/18 12:04:37 ssh_host_ecdsa_key
-rw-r--r--            162 2018/12/18 12:04:37 ssh_host_ecdsa_key.pub
-rw-r-----            387 2018/12/18 12:04:37 ssh_host_ed25519_key
-rw-r--r--             82 2018/12/18 12:04:37 ssh_host_ed25519_key.pub
-rw-r-----          1,679 2018/12/18 12:04:35 ssh_host_rsa_key
-rw-r--r--            382 2018/12/18 12:04:35 ssh_host_rsa_key.pub
-rw-------          3,907 2018/04/11 12:21:29 sshd_config
[root@c7-client ~]# rsync root@192.168.17.7:/etc/fstab
root@192.168.17.7's password: 
-rw-r--r--            465 2018/09/27 15:49:45 fstab
[root@c7-client ~]# rsync root@192.168.17.7:/etc/ssh/
[email protected]'s password: 
drwxr-xr-x            225 2018/09/27 17:28:23 .
-rw-r--r--        581,843 2018/04/11 12:21:29 moduli
-rw-r--r--          2,276 2018/04/11 12:21:29 ssh_config
-rw-r-----            227 2018/09/27 16:02:33 ssh_host_ecdsa_key
-rw-r--r--            162 2018/09/27 16:02:33 ssh_host_ecdsa_key.pub
-rw-r-----            387 2018/09/27 16:02:33 ssh_host_ed25519_key
-rw-r--r--             82 2018/09/27 16:02:33 ssh_host_ed25519_key.pub
-rw-r-----          1,679 2018/09/27 16:02:33 ssh_host_rsa_key
-rw-r--r--            382 2018/09/27 16:02:33 ssh_host_rsa_key.pub
-rw-------          3,905 2018/09/27 17:28:23 sshd_config

當使用遠程shell的時候,會提示我們輸入遠程主機的用戶密碼。由於遠程shell方式是基於SSH,因此可以事先配置好SSH的免密登錄,這樣就無需密碼了。

[root@c7-client ~]# rsync root@192.168.17.7:/etc/fstab
-rw-r--r--            465 2018/09/27 15:49:45 fstab

本地主機文件和目錄的複製,類似cp命令。

[root@c7-client ~]# rsync /etc/fstab /tmp/
[root@c7-client ~]# ls -l /etc/fstab /tmp/fstab 
-rw-r--r--. 1 root root 487 Dec 18 11:46 /etc/fstab
-rw-r--r--. 1 root root 487 Dec 19 19:04 /tmp/fstab
[root@c7-client ~]# rsync -r /etc/ssh /tmp/
[root@c7-client ~]# ls /{etc,tmp}/ssh/
/etc/ssh/:
moduli  ssh_config  sshd_config  ssh_host_ecdsa_key  ssh_host_ecdsa_key.pub  ssh_host_ed25519_key  ssh_host_ed25519_key.pub  ssh_host_rsa_key  ssh_host_rsa_key.pub

/tmp/ssh/:
moduli  ssh_config  sshd_config  ssh_host_ecdsa_key  ssh_host_ecdsa_key.pub  ssh_host_ed25519_key  ssh_host_ed25519_key.pub  ssh_host_rsa_key  ssh_host_rsa_key.pub

複製或者同步目錄的時候,需要註意一點,如果源目錄的末尾沒有斜線,則表示將源目錄整個複製到目標目錄下,就如同上面的例子;

如果源目錄的末尾有斜線,則表示將源目錄下的內容複製到目標目錄下,如下所示。

[root@c7-client ~]# rsync -r /etc/ssh/ testdir/
[root@c7-client ~]# ls /etc/ssh/ testdir/
/etc/ssh/:
moduli  ssh_config  sshd_config  ssh_host_ecdsa_key  ssh_host_ecdsa_key.pub  ssh_host_ed25519_key  ssh_host_ed25519_key.pub  ssh_host_rsa_key  ssh_host_rsa_key.pub

testdir/:
moduli  ssh_config  sshd_config  ssh_host_ecdsa_key  ssh_host_ecdsa_key.pub  ssh_host_ed25519_key  ssh_host_ed25519_key.pub  ssh_host_rsa_key  ssh_host_rsa_key.pub

遠程shell之間的文件同步。

[root@c7-client ~]# rsync c7-client.txt root@192.168.17.7:/root/
[root@c7-client ~]# rsync root@192.168.17.7:/root/c7.txt .

遠程shell之間的目錄同步。

[root@c7-client ~]# touch testdir/rsync{1,2,3}.txt
[root@c7-client ~]# rsync -r testdir/ root@192.168.17.7:/root/
[root@C7 ~]# ls -l /root/rsync{1,2,3}.txt
-rw-r--r-- 1 root root 0 Dec 19 19:17 /root/rsync1.txt
-rw-r--r-- 1 root root 0 Dec 19 19:17 /root/rsync2.txt
-rw-r--r-- 1 root root 0 Dec 19 19:17 /root/rsync3.txt
[root@c7-client ~]# rsync -r root@192.168.17.7:/root/rrr .
[root@c7-client ~]# ls -l rrr/
total 0
-rw-r--r--. 1 root root 0 Dec 19 19:19 l.txt
-rw-r--r--. 1 root root 0 Dec 19 19:19 w.txt
-rw-r--r--. 1 root root 0 Dec 19 19:19 z.txt

 

選項與示例

-v, --verbose:用於顯示同步中的詳細信息,-vvvv可以顯示更詳細的信息,一般是用於排錯的時候使用。v的個數越多,顯示的信息越詳細。

--partial:預設情況下,當傳輸中斷的時候,rsync會將已傳輸一半的目標文件刪除;如果使用該選項,則不會刪除,這樣子可以提高再次傳輸的速度,感覺類似於斷點重傳。

--progress:在同步的時候顯示進度,類似如下。

782448  63%  110.64kB/s    0:00:04

-P:該選項是--partial和--progress的結合,當同步的時間較長(文件較大較多或者網路不佳)的時候,可以使用該選項。

-n, --dry-run:用於測試,不會真正執行同步操作,而是模擬真實操作,並且模擬真實的輸出,常配合-v或者-vvvv來查看rsync是否執行正常。

-a, --archive:歸檔模式,等同於-rlptgoD,它保留了源文件的大部分元數據。但是它不包含-H選項,因為查找多鏈接的文件太消耗資源。

-r, --recursive:遞歸,用於同步目錄。如果不加該選項,當源文件是一個目錄的時候,會跳過,並返回被跳過的目錄名稱。

[root@C7 tmp]# rsync -v /foo/ /tmp/
skipping directory .

sent 16 bytes  received 12 bytes  56.00 bytes/sec
total size is 0  speedup is 0.00
[root@C7 tmp]# rsync -v /foo /tmp/
skipping directory foo

sent 16 bytes  received 12 bytes  56.00 bytes/sec
total size is 0  speedup is 0.00

這裡從輸出信息中也可以看出源文件如果是目錄,那麼末尾是否帶斜線的差異。

[root@C7 tmp]# rsync -rv /foo/ /tmp/
sending incremental file list
bar/baz.c

sent 131 bytes  received 36 bytes  334.00 bytes/sec
total size is 0  speedup is 0.00

-t, --times:保留文件的mtime,由於rsync預設檢查模式使用quick check演算法,因此建議每次同步都應該使用-t或者-a選項,否則發送端每次都會將很可能是相同的文件加入文件列表,導致了系統資源的浪費。

-o, --owner:保留文件的屬主。

-g, --group:保留文件的屬組。

--chown=USER:GROUP:文件同步後修改目標文件的ownership。該選項其實等同於“--usermap=*:USER --groupmap=*:GROUP”。不過該選項的實現是內部調用了--usermap和--groupmap,因此該選項不可以與這兩個選項混合使用。如果想要讓--chown正常使用,不可缺少-o和-g選項。

-p, --perms:保留文件的讀寫執行許可權,不包含其他特殊許可權。

--chmod:文件同步後修改目標文件的許可權。可根據文件是普通文件或者目錄分別設置不同的許可權。如果是普通文件則會加上首碼F,目錄則會加上首碼D。用法類似如下。

--chmod=Dg+s,ug+w,Fo-w,+X
--chmod=D2775,F664

如果想要讓--chown正常使用,不可缺少-o和-g選項。

因此,如果想要讓--chown和--chmod都正常使用的話,使用-a選項即可!但是具體的原因目前未知,應該是rsync對待所有權(ownership)和許可權(permission)的理解與我們人腦不同。

讓我們來驗證一下-togp選項的作用,在c7-client主機上創建了一個空文件rsync.txt,並設置了許可權和ownership,然後同步至C7主機。可以發現同步後,文件的許可權、所有權以及mtime都發生了改變。

[root@c7-client ~]# ls -l rsync.txt 
-rw-rw-rw-. 1 haimianbb haimianbb 0 Dec 25 10:06 rsync.txt
[root@c7-client ~]# rsync -v rsync.txt root@192.168.17.7:/tmp/rsync.txt
rsync.txt

sent 83 bytes  received 35 bytes  236.00 bytes/sec
total size is 0  speedup is 0.00
[root@C7 ~]# ls -l /tmp/rsync.txt 
-rw-r--r-- 1 root root 0 Dec 25 10:12 /tmp/rsync.txt

當我們使用了-togp選項之後,文件的許可權、mtime和所有權都保持了。

[root@c7-client ~]# rsync -vtogp rsync.txt root@192.168.17.7:/tmp/rsync.txt
rsync.txt

sent 113 bytes  received 35 bytes  296.00 bytes/sec
total size is 0  speedup is 0.00
[root@C7 ~]# ls -l /tmp/rsync.txt
-rw-rw-rw- 1 haimianbb haimianbb 0 Dec 25 10:06 /tmp/rsync.txt

-D:等同於--devices和--specials的結合,用於同步字元設備、塊設備以及特殊文件(socket)。

-l, --links:當遇到字元鏈接的時候,在遠程主機上創建相同的字元鏈接文件。

預設情況下,字元鏈接文件是非普通文件,會被rsync跳過。

[root@C7 tmp]# cat /tmp/name.txt 
zhangwenlong
[root@C7 tmp]# ln -s /tmp/name.txt /tmp/name.link
[root@C7 tmp]# ls -l name.link 
lrwxrwxrwx 1 root root 13 Dec 25 17:32 name.link -> /tmp/name.txt
[root@C7 tmp]# rsync -v name.link /root/name.rsync
skipping non-regular file "name.link"

sent 43 bytes  received 54 bytes  194.00 bytes/sec
total size is 13  speedup is 0.13

使用-l選項就可以同步字元鏈接文件了,同步後的文件也是一個字元鏈接文件。

[root@C7 tmp]# rsync -vl name.link /root/name.rsync
name.link -> /tmp/name.txt

sent 60 bytes  received 19 bytes  158.00 bytes/sec
total size is 13  speedup is 0.16
[root@C7 tmp]# ls -l /root/name.rsync 
lrwxrwxrwx 1 root root 13 Dec 25 17:35 /root/name.rsync -> /tmp/name.txt
[root@C7 tmp]# cat /root/name.rsync
zhangwenlong

-z, --compress:傳輸之前是否對數據進行壓縮。可以留意到壓縮後,發送的位元組數降低了。

[root@C7 tmp]# rsync -v /etc/inittab /tmp/inittab
inittab

sent 590 bytes  received 35 bytes  1,250.00 bytes/sec
total size is 511  speedup is 0.82
[root@C7 tmp]# rsync -vz /etc/inittab /tmp/inittab
inittab

sent 364 bytes  received 35 bytes  798.00 bytes/sec
total size is 511  speedup is 1.28

-R, --relative:使用相對路徑。意味著會將命令行中完整的路徑名稱發送給遠程主機,而不是只發送最後一部分的文件名。

我們先來看一下預設情況下的行為。複製/foo/bar/baz.c到/tmp/目錄下的時候,僅會在/tmp/目錄下創建baz.c文件。(從-v結果來看,應理解為僅將源文件“/foo/bar/baz.c”中的最後一部分“baz.c”加入了文件列表)

[root@C7 ~]# rsync -v /foo/bar/baz.c /tmp/
baz.c

sent 78 bytes  received 35 bytes  226.00 bytes/sec
total size is 0  speedup is 0.00

如果增加了-R選項。則是在/tmp/目錄下創建了完整的目錄結構。這是因為-R選項使得發送端rsync將整個源文件路徑“/foo/bar/baz.c”加入了文件列表。

[root@C7 ~]# rsync -vR /foo/bar/baz.c /tmp/
/foo/
/foo/bar/
/foo/bar/baz.c

sent 128 bytes  received 41 bytes  338.00 bytes/sec
total size is 0  speedup is 0.00
[root@C7 ~]# tree /tmp/foo/
/tmp/foo/
└── bar
    └── baz.c

1 directory, 1 file

像“foo/”和“foo/bar/”這種額外的路徑元素,我們就稱其為隱式目錄(implied  directories)。如果相對路徑涉及到字元鏈接的話,可能會有特殊情況,要看一下man手冊。

有的時候你可能只希望在接收端創建部分源文件路徑,那麼可以在源文件路徑中插入一個“.”和“/”。

[root@C7 tmp]# rsync -vR /foo/./bar/baz.c /tmp/
bar/
bar/baz.c

sent 100 bytes  received 38 bytes  276.00 bytes/sec
total size is 0  speedup is 0.00

這樣子相對路徑就是從bar開始的了。

--size-only:修改rsync預設的quick check演算法,僅檢查兩端文件大小。個人建議不要帶上該選項,雖然檢查的複雜度降低了,可能會提升性能,但是可能出現內容不同的文件沒得到正確的同步,在特定的環境下可能造成嚴重的後果。

就像這個例子中所示,1.txt和2.txt明明文件內容不一致,卻因為--size-only選項使得它們沒有被同步。

[root@C7 tmp]# ls -l {1,2}.txt
-rw-r--r-- 1 root root 9 Dec 21 17:21 1.txt
-rw-r--r-- 1 root root 9 Dec 21 17:22 2.txt
[root@C7 tmp]# diff {1,2}.txt
1c1
< 12345678
---
> 87654321
[root@C7 tmp]# rsync -v --size-only {1,2}.txt

sent 39 bytes  received 12 bytes  102.00 bytes/sec
total size is 9  speedup is 0.18
[root@C7 tmp]# diff {1,2}.txt
1c1
< 12345678
---
> 87654321

-c, --checksum:修改rsync預設的quick check演算法,通過檢驗碼的方式檢查兩端的文件內容是否一致,生成校驗碼會引起兩端產生大量的磁碟I/O,因此一般是不會啟用該選項

-u, --update:如果目標文件存在且mtime新於源文件的話,則跳過。如果目標文件存在且mtime等於源文件的話,則判斷size,size同則不同步,size不同則同步。該選項是傳輸規則,並不是exclude,因此不會影響文件進入文件列表,因此不會影響目標文件上的刪除操作。

-d, --dirs:用於拷貝目錄本身,但是不會拷貝目錄下的文件。有別於-r, --recursive。但是如果源文件是以“.”或者斜杠結尾的話,那麼還是會將目錄下的內容拷貝至目標文件。如果-r和-d同時使用的話,那麼-r優先。

--max-size=SIZE:限制傳輸的文件的最大size。可以帶上單位尾碼“K、KiB、M、MiB、G、GiB”,這是以1024為乘數,如果想要以1000為乘數的話,則使用“KB、MB和GB”。大小寫均可。

--min-size=SIZE:限制傳輸的文件的最小size。其他說明類似上面的--max-size,避免傳輸較小的文件或者垃圾文件。

--exclude=PATTERN:用於排除文件,被排除的文件不會被同步。涉及到man手冊中的過濾規則(FILTER RULE)。後面會詳述。

--exclude-from=FILE:排除文件,即當需要排除的PATTERN較多的時候,可以將每一個PATTERN都寫入該文件中,每個PATTERN占一行。空行以及以“#”或者“;”開頭的行會被忽略。FILE為“-”表示讀取STDIN(標準輸入)。

--delete:刪除接收端中不存在於發送端的額外的文件,僅作用於那些已經同步了的目錄。後面會詳述。

-b, --backup:當目標文件已經存在的時候,同步操作即將覆蓋或者同步操作(--delete)即將刪除目標文件的時候,對其進行備份。

[root@C7 tmp]# rsync -vb /foo/bar/baz.c /tmp/
baz.c

sent 78 bytes  received 35 bytes  226.00 bytes/sec
total size is 0  speedup is 0.00
[root@C7 tmp]# ls -l /tmp/baz.c*
-rw-r--r-- 1 root root 0 Dec 21 17:28 /tmp/baz.c
-rw-r--r-- 1 root root 0 Dec 21 17:28 /tmp/baz.c~

即便反覆執行,備份文件的文件名依然是“baz.c~”。

--backup-dir=DIR:指定備份文件的目錄。預設的備份目錄是在目標文件的當前目錄。

若備份目錄不存在,則會自動創建,並回顯。

[root@C7 tmp]# rsync -vb --backup-dir=/tmp/back/ /foo/bar/baz.c /tmp/
(new) backup_dir is /tmp/back
baz.c

sent 78 bytes  received 69 bytes  294.00 bytes/sec
total size is 0  speedup is 0.00

備份文件會是/tmp/back/baz.c,它不帶尾碼,反覆執行也依然是該文件。

--suffix=SUFFIX:指定備份文件的尾碼。預設的備份尾碼是“~”。

[root@C7 tmp]# rsync -vb --suffix=alongdidi /foo/bar/baz.c /tmp/
baz.c

sent 78 bytes  received 35 bytes  226.00 bytes/sec
total size is 0  speedup is 0.00

備份文件是/tmp/baz.calongdidi,反覆執行的話也依然是該文件。

rsync的備份機制似乎不能遞增,只能反覆覆蓋,感覺並沒有什麼卵用。

-e, --rsh=COMMAND:用於選擇一個遠程shell程式,現在所使用的一般都是SSH了(以前是RSH,但是RSH沒有加密功能),所以一般是用於指定SSH的選項。

主要用於指定ssh的參數,以及用於臨時daemon。

-e 'ssh -p 2234'
-e 'ssh -o "ProxyCommand nohup ssh firewall nc -w1 %h %p"'

--port=PORT:如果使用的rsync daemon的工作方式的時候,用於指定埠號,預設是873。

--password-file=FILE:用於指定rsync認證的密碼文件。非SSH認證的密碼。FILE可以為“-”表示讀取STDIN。如果密碼文件是全局可讀,或者以root用戶運行rsync但是密碼文件的ownership不是root的話,那麼rsync會退出。

--existing, --ignore-non-existing:告訴rsync,只更新目標文件中已存在的文件。

--ignore-existing:告訴rsync,只更新目標文件中不存在的文件。

創建了2個目錄,目錄結構如下。預設情況下,將a目錄同步至b目錄的話,除了會將a.txt加入文件列表中以外,還會將{1,2,3}.txt也加入文件列表中。

[root@C7 tmp]# tree {a,b}
a
├── 1.txt
├── 2.txt
├── 3.txt
└── a.txt
b
├── 1.txt
├── 2.txt
├── 3.txt
└── b.txt

0 directories, 8 files

如果我們只想同步接收端已存在的文件的話,則使用--existing選項。

[root@C7 tmp]# rsync -rv --existing a/ b/
sending incremental file list
1.txt
2.txt
3.txt

sent 235 bytes  received 73 bytes  616.00 bytes/sec
total size is 0  speedup is 0.00

如果我們只想同步接收端不存在的文件的話,則使用--ignore-existing選項。

[root@C7 tmp]# rsync -rv --ignore-existing a/ b/
sending incremental file list
a.txt

sent 157 bytes  received 35 bytes  384.00 bytes/sec
total size is 0  speedup is 0.00

--existing選項可以和--ignore-existing選項結合使用,結合使用的情況下不會同步任何文件,一般用於配合--delete選項實現在不傳輸任何數據的情況下,僅刪除接收端的額外文件。

可以看一下單獨使用--delete和結合使用的區別。

[root@C7 tmp]# rsync -rv --delete a/ b/
sending incremental file list
deleting b.txt
1.txt
2.txt
3.txt
a.txt

sent 274 bytes  received 101 bytes  750.00 bytes/sec
total size is 0  speedup is 0.00


[root@C7 tmp]# rsync -rv --existing --ignore-existing --delete a/ b/
sending incremental file list
deleting b.txt

sent 114 bytes  received 21 bytes  270.00 bytes/sec
total size is 0  speedup is 0.00

--remove-source-files:源文件如果同步成功,則將其刪除。

[root@C7 tmp]# tree {a,b}
a
├── 1.txt
├── 2.txt
├── 3.txt
└── a.txt
b
├── 1.txt
├── 2.txt
├── 3.txt
└── b.txt

0 directories, 8 files
[root@C7 tmp]# rsync -rv --remove-source-files a/ b/
sending incremental file list
1.txt
2.txt
3.txt
a.txt

sent 274 bytes  received 124 bytes  796.00 bytes/sec
total size is 0  speedup is 0.00
[root@C7 tmp]# tree {a,b}
a
b
├── 1.txt
├── 2.txt
├── 3.txt
├── a.txt
└── b.txt

0 directories, 5 files

 

rsync的include/exclude模式

--exclude=PATTERN:rsync通過該選項來排除所不需要同步的文件。它是--filter選項的一種簡寫形式。

一個--exclude選項只能排除一個模式,如果要排除多個模式的話,可以在命令行中書寫多次--exclude選項,或者將模式逐行寫入文件中,然後使用--exclude-from引用該模式文件。

簡單的示例如下。

[root@C7 tmp]# tree {a,b}
a
├── 1.txt
├── 2.txt
├── 3.txt
└── a.txt
b
├── 1.txt
├── 2.txt
└── 3.txt

0 directories, 7 files
[root@C7 tmp]# rsync -rv --exclude=a.txt a/ b/
sending incremental file list
1.txt
2.txt
3.txt

sent 215 bytes  received 73 bytes  576.00 bytes/sec
total size is 0  speedup is 0.00
[root@C7 tmp]# rsync -rv --exclude=a.txt a b/
sending incremental file list
a/
a/1.txt
a/2.txt
a/3.txt

sent 230 bytes  received 77 bytes  614.00 bytes/sec
total size is 0  speedup is 0.00

第二次同步的時候,如果不加--exclude選項,那麼會同步以下:

  • a/
  • a/1.txt
  • a/2.txt
  • a/3.txt
  • a/a.txt

我們排除的模式是a.txt,模式沒有以“/”開頭或者結尾,那麼只要傳輸整個名稱中某個部分包含了a.txt,就會生效。因此,a/a.txt也被排除掉了。

排除的時候,模式的書寫其實是一個難點。在man手冊中有比較詳細的描述,涉及到

  • 源文件如果是個目錄,那麼末尾是否帶上斜線。
  • 是否使用相對目錄的選項--relative。
  • 什麼是傳輸中的根目錄。
  • 模式是否以“/”開頭。若是則涉及到錨定傳輸根的概念。
  • 模式是否以“/”結尾。若是則判定為目錄。
  • 模式是否是無限制(unqualified)的,例如“foo”或者上述的“a.txt”。無限制指的是沒有以“/”開頭或者結尾。若是則匹配的靈活度是很大的。
  • 等等。

這個需要大家自行看一下man手冊以及自己反覆敲命令體驗一下,一般是帶上-avn選項來測試。

再來幾個示例,首先我們先看一下目錄a的層級結構。

[root@C7 tmp]# tree a/
a/
├── 1.txt
├── 2.txt
├── 3.txt
├── a.txt
├── index.php
└── public
    └── index.php

1 directory, 6 files

然後我們以測試的形式,同步a目錄至b目錄,註意此時同步的源目錄a的末尾帶上了斜線。首先我們看一下不帶排除選項的話,會同步哪些文件。

[root@C7 tmp]# rsync -avn a/ b/
sending incremental file list
./
1.txt
2.txt
3.txt
a.txt
index.php
public/
public/index.php

sent 232 bytes  received 41 bytes  546.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

源目錄帶上斜線,並且沒有-R選項,這時候就已經確定了傳輸根了。即這個示例中的傳輸根是a/下開始。而不是a目錄本身開始,更不是/tmp/a(案例中我的PWD目錄是/tmp)開始。

這時候我們排除無限制的index.php。

[root@C7 tmp]# rsync -avn --exclude=index.php a/ b/
sending incremental file list
./
1.txt
2.txt
3.txt
a.txt
public/

sent 175 bytes  received 35 bytes  420.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

無限制的匹配範圍很大,只要整棵樹/整個名稱中包含了模式,就會生效。因此index.php和public/index.php都會排除掉。

接下來我們來一個有限制的,排除掉傳輸根下的index.php。

[root@C7 tmp]# rsync -avn --exclude=/index.php a/ b/
sending incremental file list
./
1.txt
2.txt
3.txt
a.txt
public/
public/index.php

排除模式不改變,通過修改源目錄末尾的斜線,從而改變了傳輸根,再來看看變化。

[root@C7 tmp]# rsync -avn --exclude=/index.php a b/
sending incremental file list
a/
a/1.txt
a/2.txt
a/3.txt
a/a.txt
a/index.php
a/public/
a/public/index.php

sent 244 bytes  received 42 bytes  572.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

這個時候想要再排除a目錄下的index.php,就得輸入--exclude=a/index.php或者--exclude=/a/index.php了。

如果模式末尾帶上斜線,則表示這個模式匹配到的,一定得是一個目錄。因為index.php不是目錄,所以不會被排除了。

[root@C7 tmp]# rsync -avn --exclude=index.php/ a/ b/
sending incremental file list
./
1.txt
2.txt
3.txt
a.txt
index.php
public/
public/index.php

sent 232 bytes  received 41 bytes  546.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

 --exclude用於排除,而--include用於包含。當同一個文件,既被排除又被包含的時候,要看哪個選項放在前面。先遇到先生效。

[root@C7 tmp]# rsync -avn --exclude=index.php --include=index.php a/ b/
sending incremental file list
./
1.txt
2.txt
3.txt
a.txt
public/
public/test.txt

sent 201 bytes  received 38 bytes  478.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)
[root@C7 tmp]# rsync -avn --include=index.php --exclude=index.php a/ b/
sending incremental file list
./
1.txt
2.txt
3.txt
a.txt
index.php
public/
public/index.php
public/test.txt

sent 261 bytes  received 44 bytes  610.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

當include和exclude規則同時使用且使用了遞歸選項(-r或者-a)的時候,如果排除了某個文件的父目錄(或者爺爺目錄等更高層的目錄),那麼即便該文件被包含了並且include的規則放在最前面,該文件也仍然不會被同步。

[root@C7 tmp]# rsync -avn --include=public/index.php --exclude=public/ a/ b/
sending incremental file list
./
1.txt
2.txt
3.txt
a.txt
index.php

sent 162 bytes  received 34 bytes  392.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

 

rsync的--delete選項

選項與示例中我們已經解釋了--delete選項的作用,在上文--existing和--ignore-existing結合使用的示例中我們也初次使用了它。

根據工作方式,即可刪除本地主機上的文件,也可以刪除目標主機上的文件。如果以一個空目錄作為源文件的話,則會清空目標目錄。

當--delete選項和--exclude選項同時使用的時候,被排除的文件不會被刪除。我們來驗證一下。

文件層級結構如下。

[root@C7 tmp]# tree test{1,2}
test1
├── 1.txt
├── 2.txt
└── 3.txt
test2
├── 1.txt
├── 2.txt
├── 3.txt
├── apple.jpg
├── icon.jpg
├── my.cnf
├── mysqld.log
└── pear.jpg

0 directories, 11 files

僅刪除不排除的情況。

[root@C7 tmp]# rsync -rvn --delete test1/ test2/
sending incremental file list
deleting pear.jpg
deleting mysqld.log
deleting my.cnf
deleting icon.jpg
del

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、名詞解釋 WPF(Windows Presentation Foundation),直譯為Windows表示基礎,是專門用來編寫程式表示層的技術和工具。 大部分程式都是多層架構的,一般至少包含三層: 數據層:用於存儲數據,多由資料庫構成。 業務邏輯層:用於編寫現實的業務邏輯。 表示層:負責把數據 ...
  • 一、安裝Erlang環境 前提:erlang版本與rabbitmq版本需按照要求對應!!! 1、在安裝erlang之前先安裝下依賴文件(這一步不要忘掉了, 不然後面./configure的時候要報錯): 2、到erlang官網去下載erlang安裝包 官網地址:http://www.erlang.o ...
  • 一、名詞解釋 Code Snippet,代碼模板,是一種快速生成代碼的快捷方式,使用它可以有效地提高編程效率。 編程中可以使用Visual Studio提供的預先設置好的Code Snippet,也可以根據需要創建自己的Code Snippet。 二、使用方法演示 使用code snippet創建屬 ...
  • 作為一隻入行不久的小菜鳥,最近接觸到利用C#代碼發送郵件,做了一點小的demo練習。首先,需要配置,這邊我做的是QQ郵箱的相關的練習,練習之前,首先應該解決的問題肯定是關於伺服器的配置,這邊偷一個懶,不做一一的步驟截圖,此外文字表述能力也不及於很好的闡述清楚這個東西,附上百度經驗的鏈接吧 https ...
  • 1.查看php載入的模塊 2.查詢連接數 3.SCP轉移數據 遠程轉到本地目錄 4.查看目錄下文件夾大小,深度可設置 5.unzip解壓覆蓋文件夾 6.mysql導出導入 ...
  • 寫在前面本文翻譯自 USB Device Class Definition for Audio Devices 1998年版約定專業名詞:Audio Device Class 簡稱為UAC(USB Audio Class)5 請求5.1 標準請求UAC 支持《USB Specification》文檔... ...
  • [TOC] 1. Linux和操作系統 1.1. 什麼是操作系統 1.2. 現有操作系統 Mac, win7, win10, winXP, Android, IOS 1.3. Linux用戶目錄 Windows: Linux: (絕對) + (相對) 絕對路徑: 相對路徑: 當前路徑 · 上一個路徑 ...
  • Kubernetes(簡稱為 K8s),最初由 Google 的工程師開發和設計。Kubernetes 是用於自動部署、擴展和管理容器化應用程式的開源系統,它旨在提供跨主機集群的自動部署、擴展以及運行應用程式容器的平臺。Kubernetes 支持一系列容器工具, 包括 Docker 等。 k8s也是 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...