注意:这个问题开始变得庞大所以我重写了它。
我有一个文件夹,我想从 Time Machine 备份中恢复它。使用cp -R
可以正常工作,但某些文件夹无法通过 Time Machine UI 或 Finder 恢复。
其他用户也报告了类似的错误,并cp -R
提出了解决方法(例如从 Time Machine 恢复 - 权限错误)但我想了解:
- 为什么
cp -R
当 Finder 和 Time Machine UI 不起作用时它可以工作。 - 我是否可以通过在备份之前更改文件权限来防止错误。
确实,Finder 似乎可以使用某些权限,但不能使用某些权限。我已将错误范围缩小到用户ben
(即我)和组的文件夹wheel
。
以下是简化的再现。我有四个文件夹,其中包含迄今为止我所见过的所有者/组组合:
ben ~/Desktop/test $ ls -lea
total 16
drwxr-xr-x 7 ben staff 238 27 Nov 14:31 .
drwx------+ 17 ben staff 578 27 Nov 14:29 ..
0: group:everyone deny delete
-rw-r--r--@ 1 ben staff 6148 27 Nov 14:31 .DS_Store
drwxr-xr-x 3 ben staff 102 27 Nov 14:30 ben-staff
drwxr-xr-x 3 ben wheel 102 27 Nov 14:30 ben-wheel
drwxr-xr-x 3 root admin 102 27 Nov 14:31 root-admin
drwxr-xr-x 3 root wheel 102 27 Nov 14:31 root-wheel
每个文件都包含一个file
以相同所有者/组命名的文件:
ben ~/Desktop/test $ cd ben-staff
ben ~/Desktop/test/ben-staff $ ls -lea
total 0
drwxr-xr-x 3 ben staff 102 27 Nov 14:30 .
drwxr-xr-x 7 ben staff 238 27 Nov 14:31 ..
-rw-r--r-- 1 ben staff 0 27 Nov 14:30 file
在备份中,它们看起来像这样:
ben /Volumes/Deimos/Backups.backupdb/Ben’s MacBook Air/Latest/Macintosh HD/Users/ben/Desktop/test $ ls -leA
total 16
-rw-r--r--@ 1 ben staff 6148 27 Nov 14:34 .DS_Store
0: group:everyone deny write,delete,append,writeattr,writeextattr,chown
drwxr-xr-x@ 3 ben staff 102 27 Nov 14:51 ben-staff
0: group:everyone deny add_file,delete,add_subdirectory,delete_child,writeattr,writeextattr,chown
drwxr-xr-x@ 3 ben wheel 102 27 Nov 14:51 ben-wheel
0: group:everyone deny add_file,delete,add_subdirectory,delete_child,writeattr,writeextattr,chown
drwxr-xr-x@ 3 root admin 102 27 Nov 14:52 root-admin
0: group:everyone deny add_file,delete,add_subdirectory,delete_child,writeattr,writeextattr,chown
drwxr-xr-x@ 3 root wheel 102 27 Nov 14:52 root-wheel
0: group:everyone deny add_file,delete,add_subdirectory,delete_child,writeattr,writeextattr,chown
其中,ben-staff
可以使用 Finder 恢复而不会出现错误。root-wheel
并root-admin
要求输入密码,然后恢复而不会出现错误。但ben-wheel
不提示我输入密码并给出错误:
The operation can’t be completed because you don’t have permission to access “file”.
有趣的是,我能file
通过将其直接拖到我的本地驱动器(而不是拖动其父文件夹)来从该文件夹恢复,但是当我这样做时,它的权限会更改为ben
/ staff
。
这是恢复后三个文件夹的权限,并且其中的文件ben-wheel
已更改为ben
/ staff
。
ben ~/Desktop/test-restore $ ls -leA
total 16
-rw-r--r--@ 1 ben staff 6148 27 Nov 14:46 .DS_Store
drwxr-xr-x 3 ben staff 102 27 Nov 14:30 ben-staff
-rw-r--r-- 1 ben staff 0 27 Nov 14:30 file
drwxr-xr-x 3 root admin 102 27 Nov 14:31 root-admin
drwxr-xr-x 3 root wheel 102 27 Nov 14:31 root-wheel
有人能解释一下这种行为吗?为什么 Finder 和 Time Machine UI 会因ben
/wheel
权限而中断?为什么 可以cp -R
工作(即使没有sudo
)?
答案1
这里的问题是,Finder 对从 Time Machine 恢复的文件实施了特殊处理以保留其所有权限,但对于当前用户帐户拥有的文件(但不属于他所属的组)却失败了。
通常,使用 复制文件时cp
,不会保留其属性。可以使用 选项更改此-p
设置。
-p 使 cp 保留副本中每个源文件的以下属性:修改时间、访问时间、文件标志、文件模式、用户 ID 和组 ID(根据权限允许)。访问控制列表 (ACL) 和扩展属性 (EA)(包括资源分支)也将被保留。
在这两种情况下,您都可以复制全部或者没有任何或这些元数据。cp
足够聪明,只有在处理完所有包含的文件后才能恢复它们([来源,见附近If -p is in effect, set all the attributes
)。
如果您没有 root 权限,则不会保留所有权。原因是只有 root 才能将文件归属于非他本人的用户和他不属于的组。
为了使 Time Machine 备份在 Finder 中可查看但不可变,它们受到访问控制列表的保护,拒绝所有用户的所有修改权限。
0: group:everyone deny add_file,delete,add_subdirectory,delete_child,writeattr,writeextattr,chown
由于从备份恢复时应保留其他属性(其他 ACL、扩展属性、文件日期和权限),因此 Finder 中需要对这些文件夹进行特殊处理。它必须删除特定的 ACL 条目,但保留其他所有内容。
此外,Apple 显然希望 Finder 在从备份复制文件和目录时保留所有所有权信息。包括团体成员。
如果您的帐户不是相关目录的所有者,Finder 会要求输入管理员密码,并将复制操作交给其提升权限的帮助程序代理。当您是备份集中文件的所有者时,不会发生这种情况。
现在,发生了下列情况之一:
- 你是不是文件所有者:Finder 要求您输入密码,代理像在备份中一样恢复所有权限。
- 您是主人和文件组的成员:Finder 复制该文件并恢复该组。
- 您是主人但不是文件组的成员:Finder 复制了该文件但无法恢复其组。
这就像是尝试访问chown username:groupname
文件,如果失败则会打印错误 — — 如果您既不是root
( sudo
) 也不是username
的成员,就会这样做groupname
。
如果您复制的不是文件夹而是文件,则其行为会略有不同:虽然文件所有权会保留,但如果您不是该组的成员,则组成员身份将被丢弃。这是您在仅复制单个文件时看到的情况。
这个问题的明显解决方案是:
- 防止文件所有权导致恢复失败(即由您和您所在的组拥有)不是成员 — — 大多数情况下,这没什么用)
- 至少暂时让自己成为该特定组的成员。遗憾的是,我无法使用
dscl
命令行以不注销或重新启动的方式执行此操作。另一个副作用是,使用wheel
,您可能会遇到权限问题,具体取决于您的系统配置。
答案2
除了常规的 UNIX 文件权限(用户/组/每个人都有自己的读/写/执行权限)之外,Mac OS X 还使用访问控制列表 (ACL),允许更精细的文件/文件夹权限设置。
Time Machine 将以下 ACL 添加(附加)到所有文件:
组:每个人都拒绝 add_file、delete、add_subdirectory、delete_child、writeattr、writeextattr、chown
(上述 ACL 是特定于文件夹的,但映射到常规文件,如下所示:add_file = write、add_subdirectory = append、delete_child = <none>)
这意味着 Time Machine 备份中的所有文件/文件夹对于所有人(甚至是根用户)都是锁定的。
如果你从 Time Machine 备份手动恢复文件(即如果你不是如果你使用迁移助手,那么你的所有文件都会保留那些讨厌的 Time Machine ACL。
删除 Time Machine ACL 非常简单。您有三种选择:
1)彻底删除文件/文件夹中的 ACL(这样做没有错,但不是一个非常谨慎的策略)
2)从文件/文件夹的 ACL 中删除第一个条目(更谨慎,但不是完美的解决方案)
3)从文件/文件夹的 ACL 中删除特定限制(如果您想保留非 Time Machine 强加的 ACL,这可能是最好的选择)
对于所有三个选项,您都需要终端,您可以在/Applications/Utilities 中找到它
选项 1:挥动斧头的方法如下:
如果您知道您的桌面上名为“我的恢复文件”的文件夹中只有您的个人文件,并且您知道这些文件没有/不需要任何花哨的 ACL,那么您可以在终端窗口中输入以下内容:
chmod -R -N ~/Desktop/My\ Recovered\ 文件
(如果您不知道如何通过终端指定文件/文件夹,只需将您想要的文件/文件夹拖放到终端窗口,终端就会为您输入正确的文件/文件夹名称)
选项 2:以下是删除第一个 ACL 条目的方法
与上述示例相同。您的桌面上有一个名为“我的已恢复文件”的文件夹。但在这种情况下,您有几个带有自定义 ACL 的文件想要保留。在终端窗口中输入以下内容:
chmod -R -a# 0 ~/桌面/我的\ 恢复\ 文件
上述解决方案之所以“危险”,是因为它不是幂等的。幂等运算是一种可以反复应用的运算,在应用一次后不会改变结果。有点像将数字乘以 1。您可以继续执行此操作,但结果始终相同。
这有什么关系呢?好吧,假设您有一个文件,在 Time Machine 为其自己的 ACL 条目添加前缀之前,它已经有一个 ACL。如果您运行上述命令两次,那么您将删除 Time Machine ACL 以及您可能不想丢失的 ACL。
此外,上述解决方案对于与其他文件混合在一起的 Time Machine 文件也不理想。如果这些其他(非 Time Machine)文件中的任何一个具有 ACL,则上述命令将删除这些 ACL。
选项 3:以下是从 ACL 中删除特定限制的方法
除了可以指定要删除的 ACL 条目号之外,您还可以指定要删除的特定限制。因此,您可以这样做:
chmod -R -a "group:everyone 拒绝 add_file、delete、add_subdirectory、delete_child、writeattr、writeextattr、chown" ~
(“~” 表示“我的主目录”,例如,如果您的用户名是 bob,则“~” = “/Users/bob”)
上述命令是幂等的,这意味着您可以反复运行它而不会产生不良影响。事实上,任何人都可以随时运行它。如果您的主目录中没有被 Time Machine 锁定的文件/文件夹,则不会发生任何事情。
好的。我希望这对某些人有帮助。我昨天遇到了与 Time Machine 权限相同的问题,所以我想分享一下我的发现。
答案3
实际上,您应该使用 tmutil 从 Time Machine 备份中恢复文件。这样您就不必删除扩展属性等。
来自Mac OS X 手册页:
tmutil restore [-v] src ... dst
将快照中的项目 src 恢复到位置 dst。dst 参数模仿 cp 工具的目标路径语义。您可以提供多个要恢复的源路径。最后一个路径参数必须是目标。
使用恢复动词时,tmutil 的行为与 Finder 非常相似。自定义 Time Machine 元数据(扩展安全性和其他)将从恢复的数据中删除,而其他元数据将被保留。
执行恢复并不严格要求具有 root 权限,但 tmutil 不会进行权限预检来确定您是否能够恢复 src 或其后代。因此,根据您要恢复的内容,您可能需要 root 权限才能执行恢复,您应该提前知道这一点。这与您使用其他复制工具(如 cp 或 ditto)时遇到的行为相同。当使用 tmutil 以 root 身份进行恢复时,恢复项目的所有权将与备份中项目的状态相匹配。
因此基本上您可以像使用 cp 命令一样使用它,而不必担心内部的其余部分。
大多数情况下,当您不知道自己是否是文件的所有者或者是否具有目标目录的写权限时,您会想要使用 sudo 进行恢复。