最後更新: 2024-09-30
目錄
建立要測試的結構
mkdir -p src/scripts dst; touch src/{1..4}.txt; touch src/scripts/{a..d}.sh
tree src
src ├── 1.txt ├── 2.txt ├── 3.txt ├── 4.txt └── scripts ├── a.sh ├── b.sh ├── c.sh └── d.sh 1 directory, 8 files
exclude
--exclude=PATTERN
相當於 filter rule -f'- PATTERN'
--exclude-from
# 用一個 file 保存要 exclude 的 path
--exclude-from '/home/backup/exclude.txt'
它支援 filter rule
- "- " (dash, space) # explicitly exclude
- "+ " (plus, space) # explicitly include
- "!" # the current filter rules are cleared before adding any further rules
--exclude 的 format:
* exclude path 用的係 Src path, 與 Dst. path 沒有關係
--exclude="foo"
exclude all filename or foldername matching full foo
(只會中 foo, 不會中 foo1 foo2)
Wildcard characters: ’*’, ’?’, and ’[’
- * # matches any path component, but it stops at slashes
- ** # to match anything, including slashes
- *** # a trailing *** will match both the directory and everything in the directory
- ? # matches any character except a slash (/)
- [ # introduces a character class, such as [a-z]
--exclude="*.o" # matches a pattern
exclude all filename or foldername matching *.o
--exclude="foo/" # 尾有 "/"
exclude any folder called foo, 在任何層數的 Folder 都有效
--exclude="foo/*"
會有一個空的 Folder 在 remote
exclude 多個 folder 或 file
--exclude=FOLDER --exclude=FILE
--exclude="/foo" # "/" 開頭
To exclude a file called foo in the "root path"
* 用 "--verbose --dry-run"(-vn) 去驗證, 它們可以看到 "root path" 是什麼
--exclude="/foo/*/bar"
exclude any file called bar two levels below a directory called foo in the transfer-root directory
--exclude="/foo/**/bar"
exclude any file or folder called bar two or more levels below a directory called foo in the transfer-root directory
[測試1] src 與 src/
# 有 Folder "src" 在 dst Folder 內
rsync -avn src dst
src/
src/1.txt
...
src/scripts/
src/scripts/a.sh
...
rsync -avn src/ dst
1.txt ... scripts/ scripts/a.sh ...
[測試2] 利用 root path exclude test1.txt
rsync -avn --exclude=/src/1.txt src dst
src/ src/2.txt ...
rsync -avn --exclude=/1.txt src/ dst
2.txt 3.txt ...
[測試3] 利用 root path exclude Folder
# 在 backup script 內 exclude 某些 path (使用 root path 表達 "/root/to/path")
e.g.
# 在 backup "/" 時有效
rsync -av --exclude=/proc/* --exclude=/dev/* --exclude=/sys/* / DEST
# 在 backup "/var" 時不會略過 /var/sys/ !!
如想 backup /var 時略過 /var/cache 就要加入
--exclude=/var/cache/*
rsync -a /var DEST
include
Don't exclude files matching PATTERN
--include=PATTERN
# This option is a simplified form of the "--filter" option (-f'+ PATTERN')
--include-from=FILE
It specifies a FILE that contains include patterns (one per line)
它支援 filter rule(-, +, !)
測試
# Default 係 include ALL 的, 所以此 command 沒意思
# 所以它要配合 --exclude 才有作用
rsync -avn --include='*.sh' src/ dst/
1.txt ... scripts/ scripts/a.sh ...
include vs exclude
Notes
- 有先後次序之別
- 考先慮 folder 然後再考慮 file
[1] "--exclude" 與 "--include" 的係有先後次序之別
* 不考慮 Folder 的情況(只考慮 file) !!
# 什麼也沒有 rsync 到, 全被 --exclude='*' 略過了
rsync -avn --exclude='*' src/ dst/
# 什麼都沒有 rsync 到, 因為 --include 在 --exclude 之後
rsync -avn --exclude='*' --include='*' src/ dst/
# 有要的檔案了 (*.txt)
rsync -avn --include='*.txt' --exclude='*' src/ dst/
[2] "--include=" 與 "--exclude="係考先慮 folder 然後再考慮 file
# 什麼都沒有 rsync 到 !!
# 即使 include 先過 exclude, 但由於考慮 Folder 先, 所以 scrpits 沒有 rsync 到 dst/
rsync -avn --include='*.sh' --exclude='*' src/ dst/
解決方案
rsync -avn --include='/scripts/' --include='/*.sh' --exclude='*' src/ dst/
OR
# 一個係 folder, 另一個係 folder 內的所有層
rsync -avn --include='/scripts/' --include='/scripts/**' --exclude='*' src/ dst/
OR
rsync -avn --include='/scripts/***' --exclude='*' src/ dst/
filter
Syntax
-f, --filter=RULE
-F # a shorthand for adding two --filter rules to your command.
- --filter='dir-merge /.rsync-filter'
This tells rsync to look for per-directory .rsync-filter files
that have been sprinkled through the hierarchy and
use their rules to filter the files in the transfer.
- --filter='exclude .rsync-filter'
This filters out the .rsync-filter files themselves from the transfer.
Filter Rule
RULE [PATTERN_OR_FILENAME] RULE,MODIFIERS [PATTERN_OR_FILENAME]
If you use a short-named rule(e.g. P),
the ’,’ separating the RULE from the MODIFIERS is optional.
Rules
protect(P) # specifies a pattern for protecting files from deletion.
# => receiver-only exclude
----
exclude(-) # specifies an exclude pattern.
include(+) # specifies an include pattern.
----
clear(!) # clears the current include/exclude list (takes no arg)
hide(H) # specifies a pattern for hiding files from the transfer.(sender-only exclude)
show(S) # files that match the pattern are not hidden.(sender-only include)
risk(R) # files that match the pattern are not protected.
----
merge(.) # specifies a merge-file to read for more rules.
dir-merge(:) # specifies a "per-directory" merge-file.
# rsync will scan every directory that it traverses for the named file,
# merging its contents when the file exists into the current list of inherited rules.
# These per-directory rule files must be created on the sending side
e.g.
"protect" filter (P)
--filter 'P my-specific-logfile.log'
The filter rules allow for flexible selection of which files
to transfer (include) and which files to skip (exclude).
As the list of files/directories to transfer is built,
rsync checks each name to be transferred against the list of include/exclude patterns in turn,
and the first matching pattern is acted on
Rule file
- --filter 對應 --include 及 --exclude
- merge-file rule 對應 --include-from 及 --exclude-from
e.g.
--filter ". /etc/rsync/default.rule"
When rules are being read from a file, empty lines are ignored, as are comment lines that start with a "#".
Filter rule modifiers
-
p indicates that a rule is perishable,
meaning that it is ignored in directories that are being deleted. -
s to indicate that the rule applies to the sending side.
(it affects what files are put into the sender's file list.) - r to indicate that the rule applies to the receiving side.
-
/ specifies that the include/exclude rule should be
matched against the absolute pathname of the current item.
e.g. -f'-/ /etc/passwd' -
! specifies that the include/exclude should take effect if the pattern fails to match.
e.g. -f'-! */' would exclude all non-directories.
應用
# 只 rsync b.sh, d.sh
rsync -avn -f '. filter.rule' src/ dst/
filter.rule
- /scripts/a.sh - /scripts/c.sh + /scripts/ + /scripts/*.sh - *