使用 APFS 在 macOS 中更改符号链接的时间戳?

Posted

技术标签:

【中文标题】使用 APFS 在 macOS 中更改符号链接的时间戳?【英文标题】:Changing the timestamp of a symlink in macOS with APFS? 【发布时间】:2021-10-17 10:33:31 【问题描述】:

根据touch 的手册页,要更改符号链接上的时间戳,可以使用touch -h -t MMDDhhmm mylink

这在我的带有 APFS 的 macOS 机器上不起作用,链接的时间戳未修改,touch 跟随链接修改目标的时间戳。

这是关于 APFS 的已知事实还是有什么我不明白的?

【问题讨论】:

【参考方案1】:

答案是:macOS 捆绑的默认touch 无法更改时间戳,但touch 8.32 from GNU coreutils 可以...

有趣的是,2021 BSD 版本的 touch 也有同样的问题,不能正确处理 -h 标志。

【讨论】:

【参考方案2】:

您似乎在 macOS 中发现了一个错误。操作系统的倒数第二个主要版本根据手册页运行,但最新版本不运行。

手册页已过时,或者软件存在错误(很可能)。

您可以在此处作为普通用户向 Apple 发送反馈:'

https://www.apple.com/feedback/macos.html

或者,如果您是开发人员,则可以使用反馈助手提交错误报告,如下所述:

https://developer.apple.com/bug-reporting/

Apple 目前没有更新版本的touch,因此您无法通过升级来解决问题。正如您自己指出的那样,您可以改用 GNU 版本的touch 来完成工作。您可以通过安装 coreutils 在 Homebrew 中找到它。

touch 的 GNU 版本通过调用较新的 futimens()/utimensat() 函数来工作(在后一种情况下,将 flag 参数设置为 AT_SYMLINK_NOFOLLOW 以更改链接本身的时间戳)。

touch (287.100.2) 的 Catalina 版本通过调用旧的 lutimes() 函数来工作,该函数显式设置链接本身的时间戳。新旧 API 之间的核心区别之一是新 API 支持以纳秒为单位的时间戳,而旧 API 的分辨率较低。

Big Sur 上的 lutimes() 函数本身并没有实现系统调用,但实际上完全包含在标准库中,使用 setattrlist() 函数(导致系统调用)实际执行文件系统修改。 setattrlist() 高度依赖文件系统(即它在 HFS+ 文件系统上的工作方式与在 APFS 文件系统上的工作方式不同)。

touch (321.100.11) 的 Big Sur 版本通过直接调用 setattrlist() 函数来工作,并且只有在失败时才回退到 lutimes。不幸的是,程序员似乎忘记了需要指定在指定-h 时,必须在链接本身上进行修改。

实际的 bug 在 touch.c 的第 219 行,其中这一行:

if (!setattrlist(*argv, &ts_req, &ts_struct, sizeof(ts_struct), 0))

应该是:

if (!setattrlist(*argv, &ts_req, &ts_struct, sizeof(ts_struct), utimes_f == lutimes ? FSOPT_NOFOLLOW : 0))

你可以在 touch.c 中改变它,重新编译它,然后得到一个可以工作的二进制文件。

【讨论】:

所以如果我理解正确的话,touch.c 已经从 Catalina 变成了 Big Sur,并且在 touch 本身中引入了一个错误(这一切都是因为基础架构 Intel → AS 的底层变化) . 这与“基础设施”从 Intel 到 AS 的变化完全无关。

以上是关于使用 APFS 在 macOS 中更改符号链接的时间戳?的主要内容,如果未能解决你的问题,请参考以下文章

在 MacOS/APFS 上使用 Dropbox 智能同步释放磁盘空间的延迟 - 潜伏着啥危险?

在 macOS 上测试文件名是不是相等,尤其是在 HFS+ 和 APFS 上

MacOS 如何同时利用 APFS 和本机 UNIX (Darwin) 文件系统?

macOS磁盘工具没有apfs格式

在 macOS High Sierra 上创建 APFS RAM 磁盘

不影响现有系统数据更新MacOS Beta最新体验版本的办法