我之前已经注意到了这一点,但是当我回答“如何将目录移动到同名的目录中? ”时,它又被提出来了:
就环境变量而言,macOS 上的mktemp
实用程序与 Linux 或 BSD(或至少 OpenBSD)上的同名实用程序的行为不同。TMPDIR
要在当前目录中创建一个临时文件,我通常可以说
tmdfile=$(TMPDIR=. mktemp)
或者
tmpfile=$(TMPDIR=$PWD mktemp)
(对于带有 的临时目录也是如此mktemp -d
)。
在 macOS 上,我将不得不通过给它一个实际的模板来强制实用程序使用当前目录,如
tmpfile=(mktemp ./tmp.XXXXXXXX)
因为使用更方便tmpfile=$(TMPDIR=. mktemp)
会忽略TMPDIR
变量并/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T
在类似命名的目录下或中创建文件。
macOS 上的手册mktemp
提到
如果
-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/
但这对我没有多大帮助,因为我不知道如何更改此值。
据说macOSmktemp
实用程序来自 FreeBSD,而后者又从 OpenBSD 获得它(这肯定是很久以前的事了)。
问题:
这是 macOS 实现中的错误(或遗漏)mktemp
吗?如何从脚本中更改DARWIN_USER_TEMP_DIR
值(或_CS_DARWIN_USER_TEMP_DIR
手册中提到的)(理想情况下,我希望取消设置它以便$TMPDIR
优先)?
这是您的 Darwin用户本地目录。它的名称只是您的 MacOS用户 UUID和您的 MacOS (BSD) 用户 ID 的串联修改后的 base 32 编码。编码的前两个字母用作“桶”系统以尝试保持目录大小较小。这两个字符是用户 UUID 的编码前 10 位,因为在 base 32 中,一个数字当然是 5 位。
它的子目录是您的用户本地临时目录和用户本地缓存目录。他们的名字曾经是
-Caches-
and-Tmp-
但那些已经被缩短为C
andT
。很明显,所有这些名称都是固定不变的,除非您愿意更改您的用户 ID 或用户 UUID。当应用程序调用
confstr(_CS_DARWIN_USER_TEMP_DIR,…)
时,C 库首先尝试确保您有一个用户本地目录,然后尝试确保您在其中有一个用户本地临时目录。确保您拥有用户本地目录并非易事,因为您没有对
/var/folders
. 因此,有一个dirhelper
Mach 启动守护程序,它以超级用户权限运行,并安全地创建这些目录,响应来自应用程序的 Mach IPC 调用,来自confstr()
其 C 库中的实现。您确实具有对用户本地目录(一旦创建)的写访问权,因此如果 C 库mkdir()
尚不存在,则它们直接只是其子级。如果成功,
mktemp
程序永远不会查看TMPDIR
环境变量的值,因为mktemp
's 代码中的回退是从调用confstr()
到调用,getenv()
而不是相反。confstr(_CS_DARWIN_USER_TEMP_DIR,…)
几乎总会成功。它的失败模式是诸如dirhelper
启动守护程序无法运行,或者尝试创建子目录失败并出现目录已存在以外T
的错误。T
您可以将目录以外的其他dirhelper
内容作为/var/folders
. 禁用dirhelper
启动守护程序将导致其自身的问题,其中最重要的是/var/folders
不会被清理。拒绝自己对用户本地目录的写入权限可能会干扰它的所有其他用途,它不仅仅用于T
子目录。您最好的选择(除了提供模板)是创建
T
一个符号链接,但这仍然不是很好,因为它当然会影响您的所有正在运行的应用程序,这些应用程序可能同时想要创建一个临时的文件。变量名也不
DARWIN_USER_TEMP_DIR
是。_CS_DARWIN_USER_TEMP_DIR
它们是配置字符串的getconf
实用程序和confstr()
库函数的名称。