我试图理解 的输出rsync -n --update -av dir1/ dir2/
。有人告诉我,这应该列出所有目录,以及 . 中不存在dir2
或较新的文件dir1
。我已经在测试目录上尝试过这个:
test
test/testDir1
test/testDir1/testDir11
test/testDir1/testDir11/testFile3.txt
test/testDir1/testFile2.txt
test/testFile1.txt
test/testDir2
如果我将其复制到testCopy
,更改test/testDir1/testFile2.txt
,然后运行rsync -n --update -av test/ testCopy/
,则输出为:
./
testDir1/
testDir1/testFile2.txt
testDir1/testDir11/
testDir2/
根据我被告知的输出应该如何表现,这是我所期望的。
然而,我在其他更大的真实目录对上尝试了相同的命令,得到了截然不同的行为。举两个应该同步的目录对的例子:
./
在一种情况下,尽管有许多目录 (620) 和文件,但输出仅为。没有列出任何文件。另一方面,列出了一些(7/72)目录。没有列出任何文件。
我不明白这个输出向我展示了什么?
答案1
虽然我没有明确的文件可以指出,但这就是我认为正在发生的事情。
使用 时-v|--verbose
,将列出要传输的文件(或将要传输的文件,当-n|--dry-run
指定时)。目录只是类 Unix 操作系统中的文件,它们按照相同的规则列出。
那么,目录什么时候转移呢? (除了它们显然不存在于目标上的情况。)假设您指定-t|--times
(由 暗示-a
),它们将在时间戳更改时被传输。如果它们的属性发生了变化,也有类似的规则。
目录何时更改时间戳?通过观察,这是(至少)当目录中的文件被创建或重命名时,而不是当文件仅更改其属性(例如时间)时。
因此,如果您touch
在 中创建新文件testDir11
,testDir11
将更改时间戳并变得可传输。但如果您是touch
现有文件,则目录不会更改。
答案2
底线:
副本(命令
cp
)执行与 rsync 不同的工作。其一,它不复制时间戳。该
rsync
选项--update
将仅更新较新的文件。
假设您所做的是目录的副本,具体来说,是这样的:
#!/bin/bash
mkdir -p test/testDir2
mkdir -p test/testDir1/testDir11
echo "yes3" > test/testDir1/testDir11/testFile3.txt
echo "yes2" > test/testDir1/testFile2.txt
echo "yes1" > test/testFile1.txt
sleep 3
cp -r test/ testcopy/
这将创建两个具有相似结构的目录:
$ tree test
test
├── testDir1
│ ├── testDir11
│ │ └── testFile3.txt
│ └── testFile2.txt
├── testDir2
└── testFile1.txt
并且,副本:
$ tree testCopy/
testCopy/
├── testDir1
│ ├── testDir11
│ │ └── testFile3.txt
│ └── testFile2.txt
├── testDir2
└── testFile1.txt
这些目录看起来相同,但其实不然。之前sleep 3
的命令cp
将使所有文件的testCopy
时间不同:
$ ls -la --time-style=full-iso test/testFile1.txt
-rw-r--r-- 1 user user 5 2017-06-22 20:22:13.704512555 0000 test/testFile1.txt
$ ls -la --time-style=full-iso testCopy/testFile1.txt
-rw-r--r-- 1 user user 5 2017-06-22 20:22:16.716355225 0000 testCopy/testFile1.txt
然后,使用您指定的选项测试 rsync (不会更改任何内容)将显示以下内容:
$ rsync -n --update -va test/ testCopy/
sending incremental file list
./
testDir1/
testDir1/testDir11/
testDir2/
为什么会这样?
因为该--update
选项优先并且只会同步新的文件。副本中的文件比原始文件中的文件新。
如果我们触摸原始目录中的文件,它将被包含:
$ touch test/testFile1.txt
$ rsync -n --update -va test/ testCopy/
sending incremental file list
./
testFile1.txt
testDir1/
testDir1/testDir11/
testDir2/
完全同步(较旧或较新但不同)的内容如下:
$ rsync -n -va test/ testCopy/
sending incremental file list
./
testFile1.txt
testDir1/
testDir1/testFile2.txt
testDir1/testDir11/
testDir1/testDir11/testFile3.txt
testDir2/
如果允许执行同步(删除该-n
选项),并再次运行:
$ rsync -n -va test/ testCopy/
sending incremental file list
一切都已更新,因此无需交换任何内容。
如果一个文件发生更改(使其更新),它将被更新:
$ touch test/testDir1/testFile2.txt
$ rsync -n --update -va test/ testCopy/
sending incremental file list
testDir1/testFile2.txt
但在实际同步后,如果更新的文件就是副本中的文件。它会不是需要更换(已经是新的了)。
$ touch testCopy/testDir1/testFile2.txt
$ rsync -n --update -va test/ testCopy/
sending incremental file list