Contents

使用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的绝对链接

现在,让我们尝试使用rsyncsource_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

在这种情况下,复制链接是成功的。rsyncfile1复制到destination_directoryflink1再次是destination_directoryfile1的链接。绝对链接flink2flink4指向文件  /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没有复制链接flink2flink3 和flink4。它只复制了 flink1,因为它是一个指向目标目录中file1的链接。由于flink3将指向目标目录之外的* ../source_directory/file1* ,因此rsync没有复制flink3。它也没有复制flink2flink4,因为它们是绝对链接。

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的链接。但是,flink2flink3flink4不再是链接。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,它们都是一样的。**