我正在将文件从旧服务器移动到新服务器。当我真正执行此操作时(而不只是测试),我将在新服务器上创建所有“用户”用户(非系统用户,即 >= 1000)。我唯一担心的是,我在主目录中移动了一些文件,这些文件属于这些用户之一(例如 apache),但新服务器上不存在。我在用着
rsync -az -e ssh src dest
作为新服务器上的用户进行复制。它确实保护了用户名字(与 ids 相反)存在的用户。然而,如果没有找到用户,它不会抱怨不存在的用户,而是依靠数字 ID。该行为似乎如手册页中的本段所述:
If a user or group has no name on the source system or it has no
match on the destination system, then the numeric ID from the
source system is used instead. See also the comments on the
"use chroot" setting in the rsyncd.conf manpage for information
on how the chroot setting affects rsync’s ability to look up the
names of the users and groups and what you can do about it.
虽然我没有逐字阅读整个手册页,但我所读到的内容并没有为我提供任何抱怨不存在的用户的选项。确保新计算机上存在目录(例如 /home)下作为所有者/文件组的任何用户的最佳方法是什么。如果 rsync 无法实现,那么获取所有存在的用户/组的列表的最佳方法是什么,以便我可以手动检查它们是否存在于新计算机上,或者在复制它们之前修复它们。
概括:
如何确保运行 rsync 后,没有使用数字 id 而不是名称 id 复制任何文件?
答案1
该rsync
命令没有直接处理此问题的机制,因此我将使用不同的方法。我将扫描源文件系统树,收集其中存在的所有文件的用户名(和组):
# List of usernames owning files under 'src'
find src -printf "%u\n" | sort -u | tee /tmp/src.users
# List of group memberships for files under 'src'
find src -printf "%g\n" | sort -u | tee /tmp/src.groups
# Copy files to target system
scp -p /tmp/src.{users,groups} dest:/tmp/
然后,我将确保所有用户都存在于目标系统上,可供使用rsync
。在目标系统上运行以下命令:
# List "missing" users
getent passwd | cut -d: -f1 | sort -u | comm -13 - /tmp/src.users
# List "missing" groups
getent group | cut -d: -f1 | sort -u | comm -13 - /tmp/src.groups
答案2
我开发了一个 rsync 补丁,如果目标上不存在用户,它会抱怨。就是这样,我将它与 roaima 的用户列表一起使用。
diff -ur rsync-3.1.1-orig/uidlist.c rsync-3.1.1/uidlist.c
--- rsync-3.1.1-orig/uidlist.c 2014-04-30 13:34:15.000000000 -0600
+++ rsync-3.1.1/uidlist.c 2015-06-15 10:03:50.282216140 -0600
@@ -232,10 +232,24 @@
else if (*name && id) {
if (idlist_ptr == &uidlist) {
uid_t uid;
- id2 = user_to_uid(name, &uid, False) ? uid : id;
+ if (user_to_uid(name, &uid, False)) {
+ id2 = uid;
+ } else {
+ rprintf(FINFO,
+ "User does not exist name %s uid %u\n",
+ name, (unsigned)id);
+ id2 = id;
+ }
} else {
gid_t gid;
- id2 = group_to_gid(name, &gid, False) ? gid : id;
+ if (group_to_gid(name, &gid, False)) {
+ id2 = gid;
+ } else {
+ rprintf(FINFO,
+ "Group does not exist name %s uid %u\n",
+ name, (unsigned)id);
+ id2 = id;
+ }
}
} else
id2 = id;
我不确定这可能有什么限制,比如如果目的地是远程的,它将如何工作。它确实可以通过 ssh 将文件从远程位置复制到本地目的地,即:
rsync -az -e ssh user@host:src_location dest_location