Kus*_*nda 9 environment-variables mktemp macos
我之前已经注意到这一点,但在我回答“如何将目录移动到同名目录中? ”时它又被提出来了:
的mktemp
在MacOS实用程序不表现一样在Linux或BSD(或至少OpenBSD的)的同名的相对于所述公用事业TMPDIR
环境变量。
在当前目录下创建一个临时文件,我通常可以说
tmdfile=$(TMPDIR=. mktemp)
Run Code Online (Sandbox Code Playgroud)
或者
tmpfile=$(TMPDIR=$PWD mktemp)
Run Code Online (Sandbox Code Playgroud)
(对于带有 的临时目录也类似mktemp -d
)。
在 macOS 上,我必须通过给它一个实际模板来强制该实用程序使用当前目录,如
tmpfile=(mktemp ./tmp.XXXXXXXX)
Run Code Online (Sandbox Code Playgroud)
因为使用更方便的tmpfile=$(TMPDIR=. mktemp)
将忽略该TMPDIR
变量并/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T
在类似命名的目录下或中创建文件。
mktemp
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'
Run Code Online (Sandbox Code Playgroud)
但是例如
tmpfile=$(TMPDIR=. mktemp -t hello)
Run Code Online (Sandbox Code Playgroud)
仍然在下创建一个文件/var/folders/.../
(也在使用$PWD
代替 时.
)。
我注意到
$ getconf DARWIN_USER_TEMP_DIR
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T/
Run Code Online (Sandbox Code Playgroud)
但这对我没有多大帮助,因为我不知道如何更改此值。
mktemp
据说macOS实用程序来自 FreeBSD,而 FreeBSD 又来自 OpenBSD(这肯定是很久以前的事了)。
题:
这是 macOS 实现中的错误(或遗漏)mktemp
吗?如何从脚本中更改DARWIN_USER_TEMP_DIR
值(或_CS_DARWIN_USER_TEMP_DIR
手册中提到的值)(理想情况下我想取消设置它以便$TMPDIR
优先)?
Jde*_*eBP 14
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/
这是您的 Darwin用户本地目录。它的名称只是您的 MacOS用户 UUID和您的 MacOS (BSD) 用户 ID串联的修改后的 base 32 编码。编码的前两个字母用作“桶”系统,以尝试将目录大小保持在较低水平。这两个字符是用户 UUID 的前 10 位编码,因为在基数 32 中,一位数字当然是 5 位。
它的子目录是您的用户本地临时目录和用户本地缓存目录。他们的名字曾经是-Caches-
and-Tmp-
但那些已经缩短为C
and T
。很明显,所有这些名称都是固定且不可更改的,除非您愿意更改您的用户 ID 或用户 UUID。
当应用程序调用 时confstr(_CS_DARWIN_USER_TEMP_DIR,…)
,C 库首先尝试确保您有一个用户本地目录,然后尝试确保其中有一个用户本地临时目录。
确保您拥有用户本地目录并非易事,因为您没有对/var/folders
. 因此,有一个dirhelper
Mach 启动守护程序,它以超级用户权限运行,并安全地创建这些目录,响应来自应用程序confstr()
在其 C 库中的实现中的 Mach IPC 调用。您确实拥有对用户本地目录(一旦创建)的写访问权限,因此 C 库只是mkdir()
其子库(如果它们尚不存在)。
如果成功,mktemp
程序永远不会查看TMPDIR
环境变量的值,因为回退 inmktemp
的代码是从调用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()
库函数的名称。
归档时间: |
|
查看次数: |
1051 次 |
最近记录: |