$$在外壳中是什么意思?


143

我曾经读过一种在shell中为临时文件获取唯一文件名的方法是使用双美元符号($$)。这确实会产生不时变化的数字...但是,如果您反复调用它,它将返回相同的数字。(解决方案是只使用时间。)

我很好奇到底$$是什么,为什么会建议将其作为生成唯一文件名的一种方式。

Answers:


102

$$如注释中所述,在Bash中是进程ID,出于各种原因,用作临时文件名并不安全。

对于临时文件名,请使用mktemp命令。


35
对于只看最重要答案的人,如果写入公共可写目录(例如/ tmp),则$$甚至对于单个文件都不适用。用符号链接乱丢/ tmp很容易,这会导致脚本在不需要的地方写东西。mktemp更好。
克里斯·杰斯特·杨

4
是的,使用$$将导致讨厌的安全漏洞。不要这样
emk

7
或提出问题的人应在下面将较高评分的答案设置为可接受的答案...
jtimberman

6
我为SEO添加了“美元”。
Antoine

1
如果$$只输出pid,那怎么会“不安全”呢?安全漏洞是由于不良设计而造成的,而不是在tmp文件名中不使用PID。$$不会造成安全漏洞,缺乏远见会
打破

113

$$是bash中的进程ID(PID)。使用$$是个坏主意,因为它通常会创建竞争条件,并让攻击者破坏您的shell脚本。见,例如,所有这些人谁创建不安全的临时文件,不得不发出安全建议。

而是使用mktempmktempLinux手册页非常棒。以下是其中的一些示例代码:

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

3
谢谢。现在不推荐使用该mktemp选项-t(我认为是由于char的问题-)。使用mktemp ${tempfoo}.XXXXXX这些天。我有权更新您的帖子。
塞巴斯蒂安2014年

1
另请注意,反引号已弃用,请TMPFILE=$(mktemp)改用。
Michael Kopp


7

UNIX之类的操作系统中的每个进程都有一个(临时)唯一的标识符PID。同时运行的两个进程不能具有相同的PID,$ $$是运行脚本的bash实例的PID。

这是非常在某种意义上说,它永远不会被重复使用(实际上,PID被不断重复利用)的唯一idenifier。它所提供的是一个数字,这样,如果另一个人运行您的脚本,他们将在您的脚本仍在运行时获得一个不同的标识符。一旦死了,PID可能会被回收,其他人可能会运行您的脚本,获得相同的PID,从而获得相同的文件名。

因此,说“ $$给出一个文件名,以便如果其他人在我的实例仍在运行的同时运行相同的脚本,那么他们将获得不同的名称”,这才是真正的理智。


5

$$是您的PID。它不会真正生成唯一的文件名,除非您小心谨慎并且没有其他人使用完全相同的方式。

通常,您会创建类似/ tmp / myprogramname $$的内容

有很多方法可以解决这个问题,并且如果您要写给其他人可以写的位置,那么在许多操作系统上预测您将拥有的PID并拧紧它并不难-想象您正在运行作为根,我创建/ tmp / yourprogname13395作为指向/ etc / passwd的符号链接-然后将其写入其中。

在shell脚本中这样做是一件坏事。如果要将临时文件用于某些用途,则应使用更好的语言,至少可以让您添加“排他”标志来打开(创建)文件。然后,您可以确保您没有破坏其他东西。


3

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


3

$$是运行脚本的Shell解释器的pid(进程ID)。当前系统上运行的每个进程都不同,但是随着时间的流逝,pid会回绕,并且退出后最终会有另一个进程具有相同的pid。只要您正在运行,pid就是您唯一的。

根据上面的定义,很明显,无论您在脚本中使用$$多少次,它都会返回相同的数字。

您可以使用例如/tmp/myscript.scratch.$$作为临时文件来处理不需要非常可靠或安全的事情。最好在脚本末尾使用诸如trap命令删除此类临时文件:

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

2

它是bash进程的进程ID。任何并发进程都不会具有相同的PID。


2

$$是运行脚本的Shell的进程ID。有关更多详细信息,请参见sh或bash的手册页。可以使用命令行“ man sh”或在网上搜索“ shell手册页”来找到手册页。


2

让我第二个emk的答案-不要将$$本身用作“独特”的东西。对于文件,请使用mktemp。对于同一bash脚本中的其他ID,请使用“ $$$(date +%s%N)”来获得相当好的唯一性机会。

 -k

0

另外,您可以通过此命令获取登录用户名。例如。

echo $(</proc/$$/login id). After that, you need to use getent command.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.