rysnc命令過濾規(guī)則入門教程
0、前言
rsync 命令的過濾規(guī)則功能非常強(qiáng)大,但網(wǎng)上幾乎沒有詳解此主題的資料,讓人學(xué)習(xí)和理解有一定的難度。官網(wǎng)文檔 和man rsync
手冊是英文的,沒有什么示例說明,不好理解。即使有人翻譯了手冊,理解起來也是有一定的難度。
故而有了此教程,結(jié)合實際命令對過濾規(guī)則的相關(guān)概念、邏輯和使用技巧做一個比較透徹的講解。希望有興趣學(xué)習(xí)的朋友,可以快速的入門,節(jié)省時間。為什么說是入門呢?因為 rsync 的過濾規(guī)則相關(guān)內(nèi)容里,還包含了一些高級技巧,個人感覺實際項目中用到的機(jī)會比較少,并未包含在此教程里。
本教程主要分為以下三部分:
- 1.概述:講解 rsync 過濾規(guī)則的相關(guān)概念和內(nèi)部運(yùn)行邏輯
- 2.操作和修飾符:講解過濾規(guī)則中的操作和修飾符
- 3.匹配模式:講解過濾規(guī)則中的匹配模式
- 4.使用場景舉例:使用具體命令舉例講解過濾規(guī)則的使用技巧
1、概述
1.1 什么是 rsync 的過濾規(guī)則?
rsync 過濾規(guī)則是用于定義哪些文件要傳輸(包含某些文件)哪些文件不要傳輸(排除某些文件)的一些規(guī)則。這些規(guī)則可以直接寫在命令參數(shù)里,也可以寫在規(guī)則文件里,然后由命令引用。例如:
# 命令1.1-1:規(guī)則直接寫在命令參數(shù)里 # --include="*.php" --exclude="*" 這兩個參數(shù)配置了兩條過濾規(guī)則 # 此命令將會只同步src_dir目錄下的php文件(不包含子目錄的) rsync -av --include="*.php" --exclude="*" src_dir/ dst_dir/ # 命令1.1-2:通過規(guī)則文件配置規(guī)則 # rsync.rules 為規(guī)則文件,可以使用相對路徑或絕對路徑 rsync -av -f ". ./rsync.rules" src_dir/ dst_dir/ rsync -av -f ". /www/rsync.rules" src_dir/ dst_dir/
rsync.rules 規(guī)則文件的內(nèi)容如下(具體語法后文說明):
# 只同步php文件 + *.php - *
1.2 配置過濾規(guī)則的方式有哪些?
與過濾規(guī)則有關(guān)的選項包括主要有:
- --include=PATTERN :設(shè)定一條包含規(guī)則,如:
--include="*.php"
- --exclude=PATTERN :設(shè)定一條排除規(guī)則,如:
--exclude="*"
- --include-from=FILE :指定一個文件,文件中一行一條包含規(guī)則,以
;
或#
開頭的行為注釋,空行被忽略 - --exclude-from=FILE :指定一個文件,文件中一行一條排除規(guī)則,以
;
或#
開頭的行為注釋,空行被忽略 - --filter=RULE, -f :設(shè)定一條過濾規(guī)則,可能是排除或包含規(guī)則(如:
-f "- *.php"
),也可能其它類型的規(guī)則(如包含一個規(guī)則文件-f ". ./rsync.rules"
)
這些選項配置的規(guī)則,其本質(zhì)是一樣,只是描述方式有些差異。其中 --filter=RULE, -f
選項支持完整的規(guī)則表達(dá)語法,其它的選項都可以轉(zhuǎn)化為此選項的表達(dá)。舉例如下:
# 以下的都是命令是完全等價的,-f 方式更簡單,后文將會更多的選用 -f 的方式表達(dá) # --include="xxx" 等價于 -f "+ xxx" # --exclude="xxx" 等價于 -f "- xxx" rsync -av --include="*.php" --exclude="*" src_dir/ dst_dir/ rsync -av -filter "+ *.php" -filter "- *" src_dir/ dst_dir/ rsync -av -f "+ *.php" -f "- *" src_dir/ dst_dir/
由 --include-from 或 --exclude-from 選項引入的規(guī)則文件,相當(dāng)于每個規(guī)則前面自動加了 +
或-
。其規(guī)則文件類內(nèi)舉例如下:
# --include-from 或 --exclude-from 引用的規(guī)則文件,開頭沒有 + 或 - *.php *
1.3 過濾規(guī)則的工作方式
所有的過濾規(guī)則配置最終在 rsync 內(nèi)部會形成一個有序的規(guī)則列表,在命令行中靠前選項,其規(guī)則的排序也靠前。隨著要傳輸?shù)模ㄎ募?目錄路徑)列表的構(gòu)建,針對每個路徑,rsync 會依次讀取有序規(guī)則列表中的規(guī)則進(jìn)行檢查。當(dāng)?shù)谝粋€規(guī)則匹配成功后,立即進(jìn)行操作(包含或排除),并停止后面規(guī)則的檢查;若所有規(guī)則都不不匹配,此路徑默認(rèn)為包含。若有遞歸選項時(如-r
-a
),如果子目錄被規(guī)則排除,那么 rsync 不會遞歸檢查此目錄的內(nèi)容了,也就是此目錄下的文件和目錄不會進(jìn)行規(guī)則過濾也不會傳輸,相當(dāng)于整個子目錄都排除了。簡單總結(jié)如下:
- 規(guī)則有順序,同命令中參數(shù)配置順序(從左到右)
- 掃描文件系統(tǒng),讀?。夸浕蛭募模┞窂胶篑R上進(jìn)行規(guī)則檢查,確定包含還是排除
- 規(guī)則檢查按序進(jìn)行,若有命中立即包含或排除,并停止后續(xù)規(guī)則檢查;若無規(guī)則命中,默認(rèn)為包含
- 目錄被排除時,其下所有子目錄和文件都被排除
舉例如下:
# 此命令會同步src_dir目錄下的所有php文件(不包含子目錄的) # 因為src_dir目錄下每個文件和目錄路徑都會先由 -f "+ *.php" 規(guī)則檢查,php文件符合此規(guī)則就被包含了,后面的 -f "- *" 規(guī)則不會檢查了 # 其余類型的文件和子目錄,不符合第一個規(guī)則,繼續(xù)檢查第二個規(guī)則時,都被排除了 # 子目錄被排除后,其中即使有php文件,也不會被檢查,所以此命令不會同步src_dir目錄下子目錄中的php文件 rsync -av -f "+ *.php" -f "- *" src_dir/ dst_dir/ # 調(diào)換兩個參數(shù)的順序,則完全不一樣了 # 此命令將不會同步任何文件和目錄 # 因為第一條規(guī)則把所有文件和目錄到排除了,第二條規(guī)則沒有機(jī)會生效 rsync -av -f "- *" -f "+ *.php" src_dir/ dst_dir/ # 此命令會同步src_dir目錄下的所有php文件(包含子目錄的) # 規(guī)則 -f "+ */" 會匹配并包含所有子目錄路徑,所以 rsync 會檢查所有的子目錄,然后其中的php文件被包含了 rsync -av -f "+ *.php" -f "+ */" -f "- *" src_dir/ dst_dir/
1.4 配置過濾規(guī)則的語法
過濾規(guī)則的語法如下:
操作 [匹配模式] 操作,修飾符 [匹配模式]
操作:是諸如+
(包含)和-
(排除)。還有之前引用規(guī)則文件(-f ". ./rsync.rules"
)的.
號,其意義是包含規(guī)則文件的操作。還有其它的一些后文詳細(xì)說明。
修飾符:可用于改變規(guī)則的一些行為方式,后文詳細(xì)說明。
匹配模式:用于匹配字符串的模式,類似正則表達(dá)式,可用于檢查字符串是否符合某種模式。若符合就說是匹配的,或說命中了。中括號表示匹配模式是可選的,因為某些特殊的操作,沒有匹配模式。
操作和匹配模式之間的空格必須是一個英文空格,也可以使用_
字符代替,這在命令行中直接寫規(guī)則時,可以省略引號。例如:
# 以下兩條命令完全等價 # 省略引號的寫法應(yīng)注意其中的*號被意外擴(kuò)展為路徑了 # 建議使用空格加引號的寫法,更清晰和安全 rsync -av -f "+ *.php" -f "+ */" -f "- *" src_dir/ dst_dir/ rsync -av -f +_*.php -f +_*/ -f -_* src_dir/ dst_dir/
1.5 測試方法
若需要反復(fù)修改命令進(jìn)行測試,按照實際同步的方式,可能需要不斷的刪除目標(biāo)目錄的文件,這多少有點(diǎn)不方便。有一個解決辦法就是,稍微改變一下 rsync 命令,去掉目標(biāo)目錄不寫,則表示不實際同步數(shù)據(jù),只列出需要同步的文件/目錄列表。例如:
# 原命令 rsync -av -f "+ *.php" -f "+ */" -f "- *" src_dir/ dst_dir/ # 修改后 # 此命令并不會實際同步數(shù)據(jù),只會輸出要同步的文件/目錄列表 rsync -av -f "+ *.php" -f "+ */" -f "- *" src_dir/
2、操作和修飾符
2.1操作
規(guī)則類型是由操作決定的,操作不同可以看作是規(guī)則類型不同。操作一共有以下9種,每種操作都有對應(yīng)的標(biāo)識,分為長標(biāo)識和短標(biāo)識,一般配置時都是使用短標(biāo)識
| 序號 | 長標(biāo)識 | 短標(biāo)識 | 操作說明 | 說明 | | ---- | --------- | ------ | ------------------------------ | ---------------------- | | 1 | exclude | - | 排除操作 | 排除符合匹配模式的路徑 | | 2 | include | + | 包含操作 | 包含符合匹配模式的路徑 | | 3 | merge | . | 引入規(guī)則文件 | 參考:命令1.1-2 | | 4 | dir-merge | : | 指定每個目錄里要合并的規(guī)則文件 | 針對傳輸目錄,不常用 | | 5 | hide | H | 指定從傳輸中隱藏文件的模式 | | | 6 | show | S | 指定某些文件不會被隱藏 | | | 7 | protect | P | 指定某些文件受保護(hù)不被刪除 | | | 8 | risk | R | 指定某些文件不受保護(hù) | | | 9 | clear | ! | 清除當(dāng)前包含/排除列表 | 無匹配模式 |
最基本也是最常用的操作就是前3個,比較好理解,之前的示例里已經(jīng)有說明,這里不再重復(fù)。
2.2 修飾符
修飾符只可用于包含/排除操作(+/-),一共有以下7種。當(dāng)操作使用短標(biāo)識是,中間的逗號是可以省略的。
1.修飾符/
包含/排除操作后面的匹配模式,本來是針對傳輸目錄的相對路徑進(jìn)行匹配。加了此修飾符后,會把相對路徑轉(zhuǎn)換為絕對路徑后進(jìn)行匹配,匹配的方式和規(guī)則保持不變。例如:
# 假設(shè) src_dir 的絕對路徑未為:/www/src_dir # 命令2.2-1:此命令將同步src_dir下的所有php文件,但不包括admin.php # 當(dāng)掃描到admin.php文件時,其相對路徑是 'admin.php'。轉(zhuǎn)化為絕對路徑為 '/www/src_dir/admin.php' # 使用 '-f "-/ src_dir/admin.php"' 規(guī)則檢查時,匹配(為什么匹配請看后文匹配模式),然后排除。 rsync -av -f "-/ src_dir/admin.php" -f "+ *.php" -f "- *" src_dir/ # 同理此命令效果相同 rsync -av -f "-/ /www/src_dir/admin.php" -f "+ *.php" -f "- *" src_dir/
2.修飾符!
表示否定,對匹配結(jié)果進(jìn)行取反,把匹配成功當(dāng)做匹配失敗,把匹配失敗當(dāng)做匹配成功。例如:
# 此命令只同步src_dir下的php文件 # 掃描src_dir目錄下的文件和目錄時,php文件以外的目錄和文件都匹配失敗,取反變成匹配成功,排除 # 而php文件最終變成匹配失敗,算未命中任何規(guī)則,默認(rèn)保留 rsync -av -f "-! *.php" src_dir/ # 經(jīng)測試,/和!兩個修飾符可以同時使用 # 修改命令2.2-1 # 此命令將只同步admin.php文件 rsync -av -f "-/! src_dir/admin.php" -f "+ *.php" -f "- *" src_dir/ # 但以下命令報錯了 rsync -av -f "-!/ src_dir/admin.php" -f "+ *.php" -f "- *" src_dir/ # 但改為單引號后正常了,可能是雙引號中的某些字符被意外解析了 # 也就是多個修飾符時,順序不影響 # 這又是一條經(jīng)驗,如非必要,參數(shù)請用單引號 rsync -av -f '-!/ src_dir/admin.php' -f "+ *.php" -f "- *" src_dir/
3.修飾符C
未仔細(xì)研究,略過
4.修飾符s
未仔細(xì)研究,略過
5.修飾符r
未仔細(xì)研究,略過
6.修飾符p
未仔細(xì)研究,略過
7.修飾符x
未仔細(xì)研究,略過
3、匹配模式
包含和排除規(guī)則,都有一個匹配模式,如 過濾規(guī)則- *.php
中的字符串*.php
就是此規(guī)則的匹配模式。用于檢查匹配傳輸路徑(要同步的原目錄中文件或目錄的相對路徑,有修飾符/
時為絕對路徑)。匹配模式就是描述路徑特征的一個字符串,如 *.php
描述的就是路徑末尾的名稱()必須是.php
結(jié)尾。功能和用法類似正則表達(dá)式,但比正則表達(dá)式簡單。
傳輸路徑:是指 src_dir 中文件或目錄的相對路徑,格式類似如下:
server.php services.php session.php view.php config/ config/services.php config/session.php config/view.php routes/ routes/api.php routes/channels.php routes/console.php routes/web.php
匹配模式將是和這些路徑進(jìn)行匹配。
關(guān)于匹配模式,我一共總結(jié)了10條模式規(guī)則:
- 模式以
/
開頭時,表示模式必須匹配路徑的開始;否則可以匹配路徑中任意一層名稱。如:/*.php
- 模式以
/
結(jié)尾時,表示模式只匹配目錄,否則可以匹配目錄或文件。如:config/
- 模式中間的
/
表示路徑分隔符。如:subdir/view.php
*
匹配任意長度的任意字符,但不匹配/
。如:*.php
**
結(jié)尾時匹配任意長度的任意字符(包括/
)。如:app/**
匹配路徑"app/xx/xx/a.txt"
***
結(jié)尾時匹配任意長度的任意字符(包括/
),還包括目錄本身。如:app/***
匹配路徑"app"和"xxx/app"
?
匹配/
以外的任意一個字符[]
匹配一個某一類字符,如:[a-z]
匹配一個小寫字母,[0-9]
匹配一個數(shù)字- 模式默認(rèn)必須匹配到路徑的末尾。如:
foo
匹配"foo"
和"xx/foo"
,但不匹配"xx/foo1"
和"foo/xx"
- 路徑被匹配的部分必須是包含完整的(目錄或文件)名稱,不可從名稱中間切開。如:
foo
不匹配"xxx/afoo"
,abc/foo
不匹配"subdir/aabc/foo"
以下舉例說明各條規(guī)則的使用:
4、使用場景舉例
4.1 場景:排除某些目錄或文件不同步
此需求比較簡單,因為默認(rèn)包含所有路徑,只需設(shè)定排除規(guī)則,排除對應(yīng)的目錄或文件即可
# 排除app和vendor目錄不同步 # 注意此命令會排除名稱是app或vendor的目錄或文件,因為模式規(guī)則1 rsync -av -f '- app' -f '- vendor' src_dir/ # 此命令則只排除 src_dir 一級子目錄中的 app 和 vendor rsync -av -f '- /app/' -f '- /vendor' src_dir/ # 排除更深層次的子目錄 rsync -av -f '- /app/Admin' -f '- /vendor' src_dir/ # 排除隱藏文件/目錄 和 php文件 # 因為模式規(guī)則9,10,4,模式`.*`相當(dāng)于是要求路徑最后的名稱(文件或目錄)必須是`.`開頭 rsync -av -f '- .*' -f '- *.php' src_dir/
4.2 場景:只同步指定的子目錄
因為傳輸路徑若無規(guī)則命中默認(rèn)是包含(同步),所以若要實現(xiàn)只同步指定目錄,需主動寫過濾規(guī)則排除不需要同步的路徑。整體思路就是,先寫規(guī)則包含要同步的路徑,然后排除其余路徑。先比較簡單的只同步一級子目錄開始
只同步一級子目錄
以下所有命令均等價,只是實現(xiàn)思路不同。效果都是:只同步config目錄(包括所有子目錄和文件)
# 命令4.2-1:使用了模式規(guī)則1、4 # 因模式規(guī)則1,-f '- /*'規(guī)則排除了str_dir目錄下出config外所有的文件和子目錄 # 遞歸掃描config目錄時,因不命中任何規(guī)則,所有子目錄和文件都被默認(rèn)包含 rsync -av -f '+ config' -f '- /*' src_dir/ # 命令4.2-2:使用了模式規(guī)則4、5、9 # -f '+ config'匹配config目錄并包含 # -f '+ config/**' 匹配config目錄下所有的子目錄和文件的路徑,包含。模式規(guī)則5 # 其余所有的路徑被 -f '- *'匹配,排除。模式規(guī)則4、9 rsync -av -f '+ config/**' -f '+ config' -f '- *' src_dir/ #命令4.2-3: # -f '+ config/***' 匹配config目錄以及其所有子目錄和文件。規(guī)則6 rsync -av -f '+ config/***' -f '- *' src_dir/ #命令4.2-4: # 使用修飾符!取反,排除了config目錄以及其所有子目錄和文件路徑以外的路徑 # 相當(dāng)于只同步config目錄 rsync -av -f '-! config/***' src_dir/
擴(kuò)展:只同步多個一級子目錄
只同步config、app目錄(包括所有子目錄和文件)
# 注意兩條命令的排除規(guī)則是不同的,可以參考體會一下模式規(guī)則1 rsync -av -f '+ config' -f '+ app' -f '- /*' src_dir/ rsync -av -f '+ config/***' -f '+ app/***' -f '- *' src_dir/
只同步更深層級的子目錄
模仿只同步一級子目錄的寫法,可能會直接把命令寫成rsync -av -f '+ app/Admin' -f '- /*' src_dir/
。但此命令并不能按預(yù)期工作。原因是rsync掃描到app路徑時,并不能命中-f '+ app/Admin'
規(guī)則,然后就后面的規(guī)則排除掉了。然后就沒然后了,此命令不會同步任何文件。
明白這個問題后,修正它,然后就可寫出只同步app/Admin子目錄(包含所有子目錄和文件)的命令了,以下都是:
# 命令4.2-5: # 掃描到一級子目錄app時,其路徑并不會和規(guī)則 -f '+ app/Admin/' 匹配,因為模式規(guī)則9 # app 路徑是有規(guī)則 -f '+ app' 命中包含的。此規(guī)則若去掉,則此命令不會同步任何文件和目錄 # -f '- /*' -f '- /*/*' 兩條規(guī)則是排除所有未被前面規(guī)則包含的一級子目錄/文件和二級子目錄/文件 # app/Admin/ 下的子目錄/文件將不會在命中規(guī)則,默認(rèn)包含 rsync -av -f '+ app/Admin/' -f '+ app' -f '- /*' -f '- /*/*' src_dir/ # 命令4.2-6:效果同命令3-5 # 思路同命令4.2-4 rsync -av -f '+ app' -f '-! app/Admin/***' -f '- /*' src_dir/ #命令4.2-6:效果同命令3-6,思路則不同 # -av -f '+ app'規(guī)則包含app # -av -f '+ app'規(guī)則包含app/Admin/目錄及所有子目錄和文件 # 其余路徑由 -f "- *" 排除 rsync -av -f '+ app' -f '+ app/Admin/***' -f "- *" src_dir/ # 命令4.2-7 # -f '-! app/***'規(guī)則使用取反,只保留app子目錄 # -f '+ app/Admin/' 包含app/Admin/目錄,其余二級子目錄由規(guī)則-f "- /*/*"排除 # app/Admin/目錄下所有子目錄和文件,無規(guī)則命中,保留 rsync -av -f '-! app/***' -f '+ app/Admin/' -f "- /*/*" src_dir/
擴(kuò)展:只同步多個深層級的子目錄
與只同步一個深層級子目錄類似,也可以寫出很多不同的命令。但問了減少出錯,建議使用命令4.2-6的思路,比較簡潔。給深層的子目錄的所有父級目錄都添加好包含規(guī)則,然后深層子目錄添加***
的包含規(guī)則,最后是一條排除規(guī)則。
rsync -av -f '+ /app' -f '+ /app/Admin/***' -f '+ /vendor' -f '+ /vendor/psy' -f "- *" src_dir/
4.3 場景:快速復(fù)制目錄結(jié)構(gòu)
有時需要需要創(chuàng)建一個目錄,其子目錄層次結(jié)構(gòu)與另一個目錄結(jié)構(gòu)一樣,但不需要其中的文件,這可以用rsync命令快速完成
# 使用了修飾符!取反,排除了目錄以外的路徑。模式規(guī)則1 rsync -av -f '-! */' src_dir/ dst_dir/
5、總結(jié)
本文針對 rsync 過濾規(guī)則主要講解了4大塊內(nèi)容:配置方法、內(nèi)部運(yùn)行方式、規(guī)則語法和使用技巧舉例。其內(nèi)容都是來自官方手冊和實操測試,若有謬誤,歡迎大家批評指正。也歡迎大家在評論區(qū)溝通交流 rsync 的各種經(jīng)驗和技巧。
另外還需強(qiáng)調(diào)的是,這個不是 rsync 過濾規(guī)則的全部內(nèi)容,例如操作和修飾符的講解并不完整,命令中的其它一些與過濾有關(guān)的選項(如:--prune-empty-dirs
)也未涉及。若有更高級功能的需求,請大家查閱官方手冊。
相關(guān)文章
MongoDB學(xué)習(xí)筆記(一) MongoDB介紹與安裝方法
最近開始學(xué)習(xí)非關(guān)系型數(shù)據(jù)庫MongoDB,卻在博客園上找不到比較系統(tǒng)的教程,很多資料都要去查閱英文網(wǎng)站,效率比較低下。本人不才,借著自學(xué)的機(jī)會把心得體會都記錄下來,方便感興趣的童鞋分享討論2013-07-07ISAPI-REWRITE偽靜態(tài)規(guī)則寫法以及說明
ISAPI-REWRITE偽靜態(tài)規(guī)則寫法以及說明,很多朋友對rewrite的規(guī)則不太熟悉,這里介紹下,方便需要的朋友2012-06-06阿里云主機(jī)不能用IP訪問網(wǎng)站的解決方法(配置安全組規(guī)則搞定)
剛買了一臺阿里云主機(jī),迫不待及的試試速度,怎知網(wǎng)站訪問不了,用IP或綁定域名都無法訪問,后來提交工單才知道,需要配置安全組規(guī)則才行。針對同樣像我一樣的新手,本文就介紹一下如何在開通阿里云主機(jī)后配置安全組規(guī)則,讓網(wǎng)站能夠外網(wǎng)訪問,需要的朋友可以參考下2020-07-07