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

Changing the timestamp of a symlink in macOS with APFS?

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

这在我的带有 APFS 的 macOS 机器上不起作用,link 的时间戳未修改并且 touch 在 link 之后修改目标的时间戳。

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

答案是:与 macOS 捆绑的默认 touch 不能更改时间戳,但是 GNU coreutils 中的 touch 8.32 可以...

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

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

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

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

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

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

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

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

在 Homebrew 中找到它

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

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

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

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

实际错误在 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 中更改它,重新编译它,并获得一个可用的二进制文件。