使用 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) 文件系统?