我以前已经注意到了这一点,但是当我回答“如何将目录移动到同名目录中?”时,它又被提起了:
对于mktemp环境变量,macOS上的OpenBSD实用程序的行为与Linux或BSD (或至少OpenBSD)上的同名实用程序不同。
要在当前目录中创建临时文件,我通常可以这样说
tmdfile=$(TMPDIR=. mktemp)或
tmpfile=$(TMPDIR=$PWD mktemp)(与使用mktemp -d的临时目录类似)。
在macOS上,我必须强制该实用程序使用当前目录,方法是给它一个实际的模板,如
tmpfile=(mktemp ./tmp.XXXXXXXX)因为使用更方便的tmpfile=$(TMPDIR=. mktemp)将忽略TMPDIR变量,并在/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T或类似命名的目录下创建文件。
mktemp on macOS的手册提到
如果给出了
-t prefix选项,mktemp将根据前缀和可用的_CS_DARWIN_USER_TEMP_DIR配置变量生成一个模板字符串。如果_CS_DARWIN_USER_TEMP_DIR不可用,则回退位置是TMPDIR和/tmp。
在我的系统中,_CS_DARWIN_USER_TEMP_DIR似乎未设置:
$ getconf _CS_DARWIN_USER_TEMP_DIR
getconf: no such configuration parameter `_CS_DARWIN_USER_TEMP_DIR'但是.
tmpfile=$(TMPDIR=. mktemp -t hello)仍然在/var/folders/.../下创建一个文件(在使用$PWD代替.时也是如此)。
我注意到了
$ getconf DARWIN_USER_TEMP_DIR
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T/但这对我没有多大帮助,因为我不知道如何改变这个值。
据说,macOS mktemp实用程序来自FreeBSD,而后者又是从OpenBSD获得的(这肯定是很久以前的事了)。
问题:
这是mktemp的D27实现中的错误(或遗漏)吗?如何在脚本中更改DARWIN_USER_TEMP_DIR值(或手册中提到的_CS_DARWIN_USER_TEMP_DIR )(理想情况下,我希望取消它,以便$TMPDIR优先)?
发布于 2019-12-02 16:25:29
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/
这是您的达尔文用户本地目录。它的名称仅仅是一个修改的32基编码的连接您的MacOS用户UUID和您的MacOS (BSD)用户ID。编码的前两个字母被用作一个“桶”系统,试图保持目录大小低。这两个字符是用户UUID的前10位编码,因为在基数32中,一位数字当然是5位。
它的子目录是用户本地临时目录和用户本地缓存目录。他们以前的名字是-Caches-和-Tmp-,但他们的名字被缩写为C和T。显然,所有这些名称都是固定的和不可更改的,除非您愿意更改您的用户ID或用户UUID。
当应用程序调用confstr(_CS_DARWIN_USER_TEMP_DIR,…)时,C库首先尝试确保您有一个用户本地目录,然后尝试确保在其中有一个用户本地临时目录。
确保您有一个用户本地目录是非常重要的,因为您没有对/var/folders的写访问权。因此,有一个以超级用户权限运行的dirhelper Mach启动d mon,它安全地创建这些目录,响应来自C库中confstr()实现中的应用程序的Mach IPC调用。您确实拥有对用户本地目录的写访问权限(一旦创建),因此如果C库还不存在,则直接对其子目录进行mkdir()。
如果这样做成功了,mktemp程序永远不会考虑TMPDIR环境变量的值,因为mktemp's代码的回退是从调用confstr()到调用getenv() (而不是相反的方式)。confstr(_CS_DARWIN_USER_TEMP_DIR,…)几乎总是成功的。它的失败模式是dirhelper launch d mon无法运行,或者试图创建T子目录失败,而不是该目录已经存在的错误。
您可以将目录之外的其他内容作为T,但这将由dirhelper启动d mon定期清理,这也是删除/var/folders中的内容的内容。禁用dirhelper启动d mon会导致自身的问题,其中最不重要的是/var/folders不被清理。拒绝自己对用户本地目录的写权限可能会干扰它的所有其他用途,因为它不仅仅用于T子目录。
您的最佳选择(除了提供一个模板)是使T成为一个符号链接,但这还远远不够好,因为它当然会影响您所有正在运行的应用程序,这些应用程序可能在同一时刻希望创建一个临时文件。
DARWIN_USER_TEMP_DIR和_CS_DARWIN_USER_TEMP_DIR都不是变量名。它们是配置字符串的getconf实用程序和confstr()库函数的名称。
https://unix.stackexchange.com/questions/555058
复制相似问题