跳到主要内容

rsync

深度拷贝目录

将源目录中的内容,原封不动递归拷贝到目的目录,用 -a 参数:

rsync -av /path/to/src/ /path/to/dest/

如果不想覆盖目标目录中有同名文件,可以用 --ignore-existing

rsync -av --ignore-existing /path/to/src/ /path/to/dest/

如果要删除目的目录中多余的文件(即源目录中不存在的文件),完全以源目录的内容为准,可以用 --delete:

rsync -av --delete /path/to/src/ /path/to/dest/

拷贝时排除指定目录

--exclude 参数:

rsync -av --exclude tmp /path/to/src/ /path/to/dest/
提示

--exclude 指定的目录是源目录的相对路径,tmp 意思就是排除 /path/to/src/tmp 这个目录。

可以有多个 --exclude 表示排除多个目录,如果要排除的目录数量非常多,可以将目录列表写到文件中:

$ cat exclude-list.txt
some/subdir/linuxconfig
some/other/dir
exampledir

然后用 --exclude-from 来排除:

rsync -av --exclude-from='exclude-list.txt' /path/to/src/ /path/to/dest/

踩过的坑

目标目录不要是源目录的父目录

如果源目录是目标目录的子目录,拷贝的结果可能不符预期。

比如:

rsync -av /path/to/parent/sub/ /path/to/parent/

一个典型的场景是在编译 dockerfile 时,按照文件系统目录结构准备了各种配置文件:

config
├── etc
│   ├── nerdctl
│   │   └── nerdctl.toml
│   ├── rc.local
│   └── ssh
│   ├── 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
│   └── sshd_config
├── lib
│   └── systemd
│   └── system
│   └── rc-local.service

希望将所有配置用 rsync 一次性拷贝到根目录下:

Dockerfile
COPY ./config /config
RUN rsync -av /config/ /
注意

结果将会是镜像内很多原有的很多文件被删除。

解决方法是,每个一级子目录单独 rsync 一下:

Dockerfile
COPY ./config /config
RUN rsync -av /config/etc/ /etc/
RUN rsync -av /config/lib/ /lib/