在shell中,$$是什么意思?

161

我曾经阅读到一个在shell中用于生成临时文件唯一文件名的方法是使用双美元符号($$),这确实会产生一个随时间变化的数字...但如果你重复调用它,它会返回相同的数字。(解决方法是直接使用时间。)

我很好奇$$究竟是什么,为什么会被建议作为生成唯一文件名的方式。

12个回答

127
$$ 是bash中的进程ID(PID)。使用$$是一个不好的选择,因为它通常会创建竞态条件,并允许攻击者破坏您的shell脚本。例如,查看所有这些人创建了不安全的临时文件并不得不发布安全公告。

相反,请使用mktempLinux mktemp手册页非常好。以下是其中的一些示例代码:

tempfoo=`basename $0`
TMPFILE=`mktemp -t ${tempfoo}` || exit 1
echo "program output" >> $TMPFILE

3
谢谢。mktemp选项-t现在已被弃用(我认为是因为字符“-”存在问题)。现在应该使用mktemp ${tempfoo}.XXXXXX。我冒昧地更新了您的帖子。 - Sebastian
2
请注意,反引号已被弃用,请使用TMPFILE=$(mktemp)代替。 - Michael Kopp

113
在 Bash 中,$$ 是进程 ID。正如评论中所指出的那样,由于各种原因,将其用作临时文件名是不安全的。对于临时文件名,请使用 mktemp 命令。

38
对于只查看最佳答案的人,如果向公开可写目录(例如 /tmp)写入单个文件,使用 $$ 是不安全的。/tmp 目录很容易被符号链接弄乱,导致您的脚本将文件写入不期望的地方。相比之下,mktemp 更好。 - C. K. Young
5
是的,使用$$会导致一个严重的安全漏洞。不要这样做。 - emk
8
或者问问题的人应该将评分更高的答案置于下方作为被采纳的答案... - jtimberman
13
我会为了SEO加入“dollar dollar”。 - Antoine
3
如果$$只输出pid,它怎么可能是“不安全”的?安全漏洞是由于设计不良而不是在tmp文件名中使用PID所造成的...如果你非常关心输出到tmp的完整性,也许你根本就不应该把它放在那里?$$不会导致安全漏洞,缺乏远见才会。 - niken
有趣的是,git似乎使用$$作为合并临时文件。 - user187676

24

$$ 是当前进程的标识符。


8
在类Unix操作系统中,每个进程都有一个(暂时)唯一的标识符PID。同时运行的两个进程不能拥有相同的PID,$$指的是运行脚本的bash实例的PID。
这并不是一个永远不会被重用的唯一标识符(事实上,PID经常被重用)。它提供了一个数字,使得如果另一个人运行你的脚本,他们将获得一个不同的标识符,而你的标识符仍然在运行。一旦你的标识符死亡,PID可能会被回收,其他人可能会运行你的脚本,获得相同的PID,从而获得相同的文件名。
因此,只有说“$$提供了一个文件名,以便在我的实例仍在运行时,其他人运行相同的脚本时会获得一个不同的名称”才是合理的。

7

$$是你的PID。它并不能生成一个唯一的文件名,除非你小心谨慎并且没有其他人以完全相同的方式做过。

通常你会创建类似于/tmp/myprogramname$$这样的东西。

有很多方法可以破坏这个,如果你要写入其他人可以写入的位置,那么在许多操作系统上预测你将拥有的PID并进行搞砸并不太困难 - 想象一下你正在以root身份运行,我创建了/tmp/yourprogname13395作为符号链接指向/etc/passwd - 然后你写入它。

在shell脚本中做这件事是不好的。如果你要为某些事情使用临时文件,你应该使用一种更好的语言,至少可以让你添加“排他”标志来打开(创建)文件。然后你就可以确信你没有覆盖其他内容。


4

$$是运行您的脚本的shell解释器的进程ID(pid)。它在系统上每个正在运行的进程中都是不同的,但随着时间的推移,pid会循环,并且在您退出后,最终会有另一个具有相同pid的进程。只要您在运行,pid对您来说是唯一的。

从上面的定义可以明显看出,无论您在脚本中使用$$多少次,它都将返回相同的数字。

您可以使用例如/tmp/myscript.scratch.$$作为临时文件,用于不需要极其可靠或安全的事物。在脚本结束时删除此类临时文件是一种良好的实践,例如使用trap命令:

trap "echo 'Cleanup in progress'; rm -r $TMP_DIR" EXIT

3

$$ 是当前 shell 进程的 pid。它不是生成唯一文件名的好方法。


2

这是bash进程的进程ID,没有其他并发进程会具有相同的PID。


2

$$ 是您的脚本所在的 shell 进程 ID。有关更多详细信息,请参阅 sh 或 bash 的 man 页面。可以通过使用命令行“man sh”或通过搜索网页“shell manpage”来找到 man 页面。


2

我赞同emk的答案——不要将$$单独用作“唯一”的任何内容。对于文件,请使用mktemp。对于同一bash脚本中的其他ID,请使用“$$$(date +%s%N)”以 合理 的概率保证唯一性。

 -k

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接