3. rsync 的 include, exclude 與 filter

最後更新: 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
- *

 

Creative Commons license icon Creative Commons license icon