使用Rsync复制链接
1. 概述
rsync是一种常用的文件同步工具。当我们使用rsync传输文件时,其行为类似于cp 命令——将文件复制到目标目录。
众所周知,cp将源目录中的链接 (symlinks)作为链接复制到目标目录。在本教程中,我们将讨论使用rsync 复制链接。
2. 分析问题
让我们从一个例子开始。假设有一个目录source_directory:
$ pwd
/home/alice
$ ls –l source_directory/
total 0
-rw-r--r-- 1 alice alice 6 May 12 8:35 file1
lrwxrwxrwx 1 alice alice 5 May 12 8:35 flink1 -> file1
lrwxrwxrwx 1 alice alice 10 May 12 8:35 flink2 -> /tmp/file2
lrwxrwxrwx 1 alice alice 25 May 12 8:35 flink3 -> ../source_directory/file1
lrwxrwxrwx 1 alice alice 34 May 12 8:35 flink4 -> /home/alice/source_directory/file1
让我们了解source_directory的内容:
- file1 : 一个普通文件
- flink1:直接指向file1的相对链接
- flink2:指向不同目录中文件的绝对链接,/tmp/file2
- flink3:间接指向file1的相对链接
- flink4:指向file1的绝对链接
现在,让我们尝试使用rsync将source_directory的内容复制 到另一个目录destination_directory:
$ rsync source_directory/* destination_directory
skipping non-regular file “flink1”
skipping non-regular file “flink2”
skipping non-regular file “flink3”
skipping non-regular file “flink4”
我们没有使用rsync的任何选项。根据rsync的输出,我们似乎无法复制任何链接。让我们检查destination_directory的内容:
$ ls –l destination_directory/
total 0
-rw-r--r-- 1 alice alice 6 May 12 8:35 file1
很明显,我们只能复制常规文件file1。我们的目标也是复制链接。
3. 使用*-l*选项
我们可以使用rsync的-l*选项来复制链接。rsync使用此选项将源目录中的链接作为链接复制到目标目录。*
让我们使用*-l选项将source_directory的内容复制到destination_directory*:
$ rm -f destination_directory/*
$ rsync -l source_directory/* destination_directory/
$ ls -l destination_directory/
total 0
-rw-r--r-- 1 alice alice 6 May 12 8:35 file1
lrwxrwxrwx 1 alice alice 5 May 12 8:35 flink1 -> file1
lrwxrwxrwx 1 alice alice 10 May 12 8:35 flink2 -> /tmp/file2
lrwxrwxrwx 1 alice alice 25 May 12 8:35 flink3 -> ../source_directory/file1
lrwxrwxrwx 1 alice alice 34 May 12 8:35 flink4 -> /home/alice/source_directory/file1
在这种情况下,复制链接是成功的。rsync将file1复制到destination_directory。flink1再次是destination_directory中file1的链接。绝对链接flink2和flink4指向文件 /tmp/file2 和 /home/alice/source_directory/file1,就像source_directory 中的那些。
但是,flink3指向*../source_directory/file1*,而不是*../destination_directory/file1*。尽管source_directory中的flink3指向同一目录中的file1 ,但rsync将链接视为指向外部目录,因为链接路径中的双点 (..) 。因此,它指向destination_directory中的*../source_directory/file1*。
我们也可以使用–links选项代替-l。两个选项都是一样的。**
** rsync的*-a或–archive选项也可用于复制链接。此选项是rsync的其他几个选项的集合。它包括-l*选项。**
尽管我们在示例中仅将链接复制到文件,但我们也可以以相同的方式将链接复制到目录。但是,我们必须使用rsync的**-r选项来复制目录。
4. rsync链接的其他选项
-l选项不是rsync用于复制链接的唯一选项。它还有其他几个选项。让我们来看看其中的一些。
4.1. –safe-links选项
如果我们只想复制指向目标目录内的链接,我们可以使用–safe-links*选项。在这种情况下, rsync也会忽略任何绝对链接*:
$ rm –f destination_directory/*
$ rsync –l –-safe-links source_directory/* destination_directory/
$ ls -l destination_directory/
total 0
-rw-r--r-- 1 alice alice 6 May 12 8:35 file1
lrwxrwxrwx 1 alice alice 5 May 12 8:35 flink1 -> file1
如我们所见,rsync没有复制链接flink2、flink3 和flink4。它只复制了 flink1,因为它是一个指向目标目录中file1的链接。由于flink3将指向目标目录之外的* ../source_directory/file1* ,因此rsync没有复制flink3。它也没有复制flink2和flink4,因为它们是绝对链接。
4.2. –copy-unsafe-links选项
** –copy-unsafe-links选项是另一个可用选项。当我们使用此选项时,rysnc将指向源目录之外的链接视为常规文件**:
$ rm –f destination_directory/*
$ rsync –l –-copy-unsafe-links source_directory/* destination_directory/
$ ls -l destination_directory/
total 0
-rw-r--r-- 1 alice alice 6 May 12 8:35 file1
lrwxrwxrwx 1 alice alice 5 May 12 8:35 flink1 -> file1
-rw-r--r-- 1 alice alice 0 May 12 8:35 flink2
-rw-r--r-- 1 alice alice 6 May 12 8:35 flink3
-rw-r--r-- 1 alice alice 6 May 12 8:35 flink4
如我们所见,flink1像以前一样被复制为file1的链接。但是,flink2、flink3和flink4不再是链接。rsync传输的是这些链接引用的文件,而不是链接本身。
4.3. -L选项
** -L选项对于将所有链接作为常规文件传输很有用。在这种情况下不会创建链接**:
$ rm –f destination_directory/*
$ rsync –L source_directory/* destination_directory/
$ ls -l destination_directory/
total 0
-rw-r--r-- 1 alice alice 6 May 12 8:35 file1
-rw-r--r-- 1 alice alice 6 May 12 8:35 flink1
-rw-r--r-- 1 alice alice 0 May 12 8:35 flink2
-rw-r--r-- 1 alice alice 6 May 12 8:35 flink3
-rw-r--r-- 1 alice alice 6 May 12 8:35 flink4
从输出中可以明显看出,所有链接都被复制为常规文件。
我们也可以使用–copy-links选项代替-L,它们都是一样的。**