我想备份我的/home
目录同步。我读过 rsync 的手册页并决定使用过滤规则来完成此任务。
我想实现的目标: 排除目录中的所有文件和目录Repos
,但保留所有pull_all.sh
文件和目录output
目录--- 无论它们位于Repos
目录中的哪个位置。
到目前为止,我最终得到了以下过滤器列表,但这仅备份pull_all.sh
文件而不output
备份目录:
# Files prefixed with "+ " are included. Files prefixed with "- " are excluded.
#
# The order of included and excluded files matters! For instance, if a folder
# is excluded first, no subdirectory can be included anymore. Therefore,
# mention included files first. Then, mention excluded files.
#
# See section "FILTER RULES" of rsync manual for more details.
# Included Files
# TODO: This rules do not work properly!
+ output/***
+ pull_all.sh
- Repos/**
# Excluded Files
- .android
- .cache
...
我在脚本中使用过滤器列表run_rsync.sh
:
#!/bin/bash
date="$(date +%Y-%m-%d)"
hostname="$(hostname)"
# debug_mode="" # to disable debug mode
debug_mode="--list-only"
# Note: With trailing "/" at source directory, source directory is not created at destination.
rsync ${debug_mode} --archive --delete --human-readable --filter="merge ${hostname}.rsync.filters" --log-file=logfiles/$date-$hostname-home.log --verbose /home backup/
不幸的是,现有的 StackExchange 线程并没有解决我的问题:
- https://stackoverflow.com/questions/8270519/rsync-exclude-a-directory-but-include-a-subdirectory
- 使用 Rsync 包含和排除选项包含目录和子目录但排除子目录中的文件
这里出了什么问题?
[更新] 以下是主目录的外观以及要保留哪些文件以及要忽略哪些文件的示例:
user@hostname:~$ tree /home/ | head
/home/
└── user
├── Desktop -> keep this
│ ├── file1 -> keep this
│ └── file2 -> keep this
├── Documents -> keep this
├── Repos
│ ├── pull_all.sh -> keep this
├── subdir1
│ ├── output -> keep this
├── subdir2
├── another_subdir
├── output -> keep this
├── subdir3 -> do not keep (because does not contain any "output")
├── file3 -> do not keep
答案1
稍微重申一下我对您的要求的解释,
- 包含所有
pull_all.sh
文件,无论我们在哪里找到它们 - 包括所有
output
目录及其内容无论我们在哪里找到它们 - 排除
Repos
除我们已经说明的目录之外的目录 - 包括其他一切
这可以指定如下
rsync --dry-run --prune-empty-dirs -av
--include 'pull_all.sh'
--include 'Repos/**/output/***'
--include '*/'
--exclude 'Repos/***'
/home backup/
一些笔记
- 这
--include '*/'
是必需的,以便rsync
考虑向下进入Repos
目录树(以查找pull_all.sh
文件),否则最终--exclude
语句将排除该文件。 - 三种不同的用途
*
是不同的:*
匹配除/
字符之外的任何内容**
匹配任何内容,包括/
字符dir/***
是相当于指定dir/
and 的快捷方式dir/**
。
- 该
--prune-empty-dirs
标志停止rsync
创建空目录,这尤其重要,因为我们需要处理Repos
目录树以查找pull_all.sh
项目output
。 --dry-run
当您对结果满意时删除。
答案2
您可以使用“+”表示所需的子目录,使用“-”表示其余目录:
rsync -auv "${src}" "${dst}" \
--filter=+_"/parent-dir/to-sync-child-dir/" \
--filter=-_"/parent-dir/*"