为什么 POSIX 中没有 mktemp 命令?

Psy*_*aut 18 shell-script posix mktemp

shell 脚本需要做的最常见的事情之一是创建和操作临时文件。这样做安全是一种痛苦,因为你需要避免名称冲突,避免竞争条件,确保该文件具有正确的权限,等等(参见GNU Coreutils的手册琐碎的博客文章这方面的迹象对这些更详细的讨论问题。)大多数类 Unix 操作系统通过提供mktemp处理所有这些问题的命令来解决这个问题。但是,这些mktemp命令的语法和语义没有标准化。如果您真的想安全可移植地创建临时文件,则必须求助于丑陋的杂物,例如以下内容:

tmpfile=$(
  echo 'mkstemp(template)' |
    m4 -D template="${TMPDIR:-/tmp}/baseXXXXXX"
) || exit
Run Code Online (Sandbox Code Playgroud)

(此变通方法利用了宏处理器m4是 POSIX 的一部分这一事实,并m4公开了mkstemp()同样由 ​​POSIX 定义的 C 标准库函数。)

鉴于这一切,为什么 POSIX 没有标准化一个mktemp命令,保证它的存在和至少它行为的某些方面?这是 POSIX 委员会的一个明显疏忽,还是委员会mktemp实际上已经讨论了标准化的想法并因某些技术或其他原因被拒绝?

Sté*_*las 17

这会定期出现在 Austin Group 的邮件列表中,我并不认为 Open Group 会反对指定它。它只需要有人提出一些建议。例如,请参阅 2011 年来自 Eric Blake(Red Hat,参加每周 POSIX 会议)的消息(此处从 gmane 复制):

Date: Tue, 10 May 2011 07:13:32 -0600
From: Eric Blake <eblake-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: Nico Schottelius <nico-posix-xuaVFQXs+5hIG4jRRZ66WA@public.gmane.org>
Cc: austin-group-l-7882/jkIBncuagvECLh61g@public.gmane.org
Newsgroups: gmane.comp.standards.posix.austin.general
Subject: Re: No mktemp in posix?
Organization: Red Hat
Message-ID: <4DC939FC.2040407@redhat.com>
References: <20110510105051.GA1767@ethz.ch>
Xref: news.gmane.org gmane.comp.standards.posix.austin.general:4151

On 05/10/2011 04:50 AM, Nico Schottelius wrote:
> Good morning,
>
> digging through Issue 7, I haven't found any utility that gives
> the ability to create a secure, temporary file that is usually
> implemented in mktemp.

echo 'mkstemp(fileXXXXXX)' | m4

will output the name of a just-created temporary file.  However, I agree
that there does not seem to be any standardized utility that gives
mkdtemp functionality, which is often more useful than mkstemp (after
all, once you have a secure temporary directory, then you can create
secure fifos within that directory, rather than having to wish for a
counterpart 'mkftemp' function).

> Is there no mktemp utility by intent or can we add it in the
> next issue?

I know both BSD and GNU have a mktemp(1) that wraps mktemp(), mkstemp(),
and mkdtemp().  In my inbox, I have record of some off-list email in
February of this year regarding some work between those teams to try and
converge on some common functionality and to word that in a manner
appropriate for the standard, although I can't find any publicly
archived messages to that effect.  But yes, I think adding mktemp(1) to
the next revision of the standard would be worthwhile.  I'll try to
revive those efforts and actually post some proposed wording.

--
Eric Blake   eblake-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org    +1-801-349-2682
Libvirt virtualization library http://libvirt.org
Run Code Online (Sandbox Code Playgroud)

在最近的一个线程(值得一读)中,Geoff Clare(来自 Open Group):

Date: Wed, 2 Nov 2016 15:13:46 +0000
From: Geoff Clare <gwc-7882/jkIBncuagvECLh61g@public.gmane.org>
To: austin-group-l-7882/jkIBncuagvECLh61g@public.gmane.org
Newsgroups: gmane.comp.standards.posix.austin.general
Subject: Re: [1003.1(2013)/Issue7+TC1 0001016]: race condition with set -C
Message-ID: <20161102151346.GB24416@lt.loopback>
Xref: news.gmane.org gmane.comp.standards.posix.austin.general:13408

Stephane Chazelas <stephane.chazelas-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote, on 02 Nov 2016:
>
> At the moment, there's no way (that I know) to create a temp file
> reliably with POSIX utilities

Given an m4 utility that conforms to the 2008 standard, there is:

tmpfile=$(echo 'mkstemp(/tmp/fooXXXXXX)' | m4)

However, I don't know how widespread support for the new mkstemp()
macro is.

--
Geoff Clare <g.clare-7882/jkIBncuagvECLh61g@public.gmane.org>
The Open Group, Apex Plaza, Forbury Road, Reading, RG1 1AX, England
Run Code Online (Sandbox Code Playgroud)

(这是我学到你在你的问题中提到的那个技巧的地方)。


sch*_*ily 7

mktemp(1)实用程序由 OpenBSD-2.1 引入,最初发布于 1997 年 6 月 1 日。

同时它可在包括 Solaris 和 Linux 在内的各种平台上使用。

如果您希望将其纳入 POSIX 标准,那么如果您对相关标准文本提出建议,那么完成此任务的机会很大。

请注意,POSIX 并不进行“发明”,但由于该程序已经存在于至少一个经过认证的平台上,因此这不是问题。

每个人都可以在https://austingroupbugs.net/提出建议, 只需申请一个帐户并制作“错误报告”

如果您想提出这样的建议,您的作业将是研究所有可用实现的最小公分母(即检查 *BSD、Solaris 和 Linux 的共同点)并编写一个描述最小公分母的手册页。不要忘记提及由于不同实现的不兼容行为而可能存在的未指定或未定义的行为。

如果您做好了功课,并且您的文本提案在本月底之前可用,并且不需要进行太多修正即可获得奥斯汀核心小组电话会议的批准,那么很有可能将其包含在下一个标准版本中(第 8 期)预计将于明年得到 Austin 小组的批准,随后得到 IEEE 的批准。我们刚刚在内部发布了新标准版本的草案 1.1。如果没有进入第 8 期,则需要几年时间才能有机会进入第 9 期。

为了让您了解将要添加到 POSIX 的重要程序需要付出哪些努力,我与Hasso Plattner Institute 的一名学生一起为 、 和 familygettext(1)编写xgettext(1)msgfmt(1)一份POSIX 标准文本提案,如下:gettext(3)这是一月到三月研讨会的一部分,我们已经在奥斯汀核心小组的电话会议上又花了三个月的时间(每周两次)。

  • mktemp 并非起源于 OpenBSD。请参阅[我在另一个问答中的评论](/181937/how-create-a-temporary-file-in-shell-script/181944#comment303201_181944)。mktemp 起源于 HP/UX,具有不同的语法。Todd C. Miller 在 90 年代中期为 OpenBSD 创建了一个不同的工具(被 FreeBSD 和 NetBSD 复制),后来又将其作为独立实用程序提供(www.mktemp.org)。这是 Linux 上通常使用的工具,直到 2007 年将(大部分兼容的)mktemp 实用程序添加到 GNU coreutils 中。 (2认同)