1

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

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

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

4

2 回答 2

1

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

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

您可以在这里以普通用户的身份向 Apple 发送反馈:'

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

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

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

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

GNU 版本touch通过调用较新的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指定,修改必须在链接本身上进行。

实际的错误在 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 中改变它,重新编译它,然后得到一个可以工作的二进制文件。

于 2021-08-16T12:52:25.633 回答
0

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

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

于 2021-08-14T16:05:38.573 回答