解决Unison跨机器同步时的权限问题

本文探讨了在不同Linux机器间使用Unison进行文件同步时遇到的权限问题。作者对比了个人和工作机器的不同用户权限设置,并测试了perms=0等配置,分析了同步失败的原因,讨论了ext4与vfat文件系统对权限处理的影响,为跨机器同步提供了技术参考。

unison permissions between machines

我有两台Linux计算机:

  • 个人机器(Arch,拥有root权限)
  • 工作机器(Ubuntu,无root权限)。

我使用“Unison”将选定的目录从一台计算机,通过一个ext4格式的U盘,同步到另一台计算机。 我个人机器上用户的UID与工作机器上系统管理员的UID相同,并且两个用户的umask都是0022(编辑:这两个用户的用户名碰巧也不同)。 最初,我没有为Unison使用任何特殊设置,两台计算机之间的权限出现了一些问题。 昨天我发现,在我的个人机器上,我无法打开在工作机器上创建的文件。 我决定在我的Unison配置文件中切换到perms = 0设置,但现在情况似乎变得更糟了。 处理这种情况的最佳方式是什么? 我应该从头开始使用perms=0重新同步,还是有其他Unison设置(或组合设置)可以让这个配置顺利工作?如果我把U盘的文件系统改成exFAT来避免这类问题,会有好处吗?

更新: 尝试创建一个可复现的例子(不使用perms=0)。

我有一个名为test的目录,在个人机器的ext4文件系统上创建,并同步到了U盘。 我将它从U盘同步到工作机器家目录下创建的test目录,工作机器的文件系统也是ext4。 在工作机器的test目录内,创建一个简单的.odt文件。

目前,从工作机器上看到:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
❯ la /media/u0183918/sandisk256/test    # U盘
total 8.0K
drwxrwx--- 2 sysmn gdm 4.0K Nov 26 09:44 figures/
drwxrwx--- 2 sysmn gdm 4.0K Nov 25 14:15 supplementary_code/
u0183918@set-l-lm25udx9w ~

❯ ls -ld /media/u0183918/sandisk256/test
drwxr-xr-x 4 sysmn gdm 4096 Nov 26 09:37 /media/u0183918/sandisk256/test/

❯ la ~/test
total 20K
drwxrwx--- 2 u0183918 domain users 4.0K Nov 26 09:44 figures/
drwxrwx--- 2 u0183918 domain users 4.0K Nov 26 09:43 supplementary_code/
-rw-r--r-- 1 u0183918 domain users 8.7K Nov 26 09:46 testfile.odt

❯ ls -ld ~/test
drwxr-xr-x 4 u0183918 domain users 4096 Nov 26 09:46 /home/u0183918/test/

创建testfile.odt后,我尝试再次同步:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
❯ unison ~/test /media/u0183918/sandisk256/test/
Unison 2.53.7 (ocaml 5.2.0): Contacting server...
Looking for changes
Reconciling changes

u0183918/...   sandisk25...
new file ---->            testfile.odt  [f]

1 items will be synced, 0 skipped
8.7 KiB to be synced from u0183918/test to sandisk256/test
0 B to be synced from sandisk256/test to u0183918/test

Proceed with propagating updates? []
No default command [type '?' or F1 for help]
Proceed with propagating updates? [] y
Propagating updates


Unison 2.53.7 (ocaml 5.2.0) started propagating changes at 09:56:05.91 on 26 Nov 2025
[BGN] Copying testfile.odt from /home/u0183918/test to /media/u0183918/sandisk256/test
Failed [testfile.odt]: Error in copying locally:
Permission denied [open(/media/u0183918/sandisk256/test/.unison.testfile.odt.ed66d4eef79419d08dc915c1bfb9a751.unison.tmp)]
Unison 2.53.7 (ocaml 5.2.0) finished propagating changes at 09:56:05.91 on 26 Nov 2025, 0.000 s


Saving synchronizer state
Synchronization incomplete at 09:56:05  (0 items transferred, 0 skipped, 1 failed)
  failed: testfile.odt

rsync -auv替换unison会导致类似的权限问题。


回答

这也有益吗?如果我把U盘的文件系统改成exFAT来避免这类问题?

“让我们再破坏一些系统,希望它能解决一个我并不真正理解的问题”:抱歉,听起来就是这样!我们避免这样做。(另外,不,这不会让情况变得更好。) 相反,你应该试着去理解你想要解决的问题。你在这里处理的似乎不是你应该解决的问题。

我应该从头开始使用perms=0重新同步吗?

不。你根本不应该设置perms=0(这在任何情况下都无益);你应该移除这个设置。 Unison通过用户和组的名称来映射文件所有者和组。因此,例如,如果你在工作机器和个人机器上都是arismav,那么一切正常;你遇到的任何问题都需要通过其他方式解决,而不是设置perms=0。就此打住。 你应该移除这个设置,并可能朝同一个方向再次同步以恢复预期的权限。 按用户名映射的替代方案: 你可以通过使用numericids按uid进行映射,但这听起来并不是你想要的:

我个人机器上用户的UID与工作机器上系统管理员的UID相同

所以,因为这意味着你工作机器上的用户uid与私人机器上的用户uid不同,所以这行不通。 通常,更复杂的同步解决方案通过实现某种允许在不同机器上的不同uid或用户名之间进行转换的表来解决这个问题。Unison不支持这个。你可以绕过这个问题,但这是一个单独的话题,可以在你确定需要时进行讨论。


你的unison命令并没有尝试连接远程服务器,因为两端都指定为本地路径。这将同步两个本地目录树~/test/media/u0183918/sandisk256/test

1
unison ~/test /media/u0183918/sandisk256/test

由于目录/media/u0183918/sandisk256/test在此服务器上不存在,该命令将因权限失败而失败(你不是root,因此无法在/media下创建目录树)。 你可能需要这样的命令:

1
unison -batch -prefer newer ~/test ssh://personalServer/media/u0183918/sandisk256/test

重申原文的一个观点:

如果我把U盘的文件系统改成exFAT来避免这类问题,会有好处吗?

刚刚使用另一个vfat文件系统的U盘测试了上面的最小示例,它似乎可以无缝工作(至少,在我测试的简单场景中)。 这样的设置会有什么缺点吗?

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计