$$在shell中意味着什么?

时间:2008-09-16 23:59:33

标签: shell scripting

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

我很想知道$$实际上是什么,以及为什么会建议它作为生成唯一文件名的方法。

12 个答案:

答案 0 :(得分:106)

$$是bash中的进程ID(PID)。使用$$是一个坏主意,因为它通常会创建竞争条件,并允许攻击者破坏您的shell脚本。例如,请参阅创建不安全临时文件并且必须发布安全建议的所有these people

相反,请使用mktempLinux man page for mktemp很棒。以下是一些示例代码:

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

答案 1 :(得分:88)

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

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

答案 2 :(得分:17)

$$是当前流程的ID。

答案 3 :(得分:6)

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

这是一个唯一的标识符,因为它永远不会被重用(实际上,PID会不断重复使用)。它给你的功能是一个数字,如果另一个人运行你的脚本,当你的脚本仍在运行时,他们会得到一个不同的标识符。一旦你死了,PID可以被回收,其他人可能会运行你的脚本,得到相同的PID,所以得到相同的文件名。

因此,只有说“$$给出一个文件名,如果其他人运行相同的脚本,我的实例仍在运行,他们会得到一个不同的名称”,这真的很明智。

答案 4 :(得分:4)

$$是你的PID。它并没有真正生成一个唯一的文件名,除非你小心,没有其他人以完全相同的方式。

通常你会创建像/ tmp / myprogramname $$

这样的东西

有很多方法可以解决这个问题,如果你写的是其他人可以写的地方,那么在许多操作系统上预测你将会拥有什么样的PID并且很难搞乱 - 想象一下'以root身份运行,我创建/ tmp / yourprogname13395作为指向/ etc / passwd的符号链接 - 然后你写入它。

在shell脚本中做这件事很糟糕。如果您打算使用临时文件,您应该使用更好的语言,这至少可以让您添加“独占”标志来打开(创建)文件。然后你可以确定你没有破坏别的东西。

答案 5 :(得分:2)

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

答案 6 :(得分:2)

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

答案 7 :(得分:2)

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

 -k

答案 8 :(得分:1)

这是bash进程的进程ID。没有并发进程将具有相同的PID。

答案 9 :(得分:1)

$$是运行脚本的shell解释器的pid(进程ID)。现在在系统上运行的每个进程都不同,但随着时间的推移,pid会回绕,并且在你退出之后将会有另一个具有相同pid的进程。只要你正在运行,pid就是你所独有的。

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

您可以使用,例如/tmp/myscript.scratch.$$作为临时文件,用于不需要非常可靠或安全的东西。在脚本末尾删除此类临时文件是一种很好的做法,例如使用trap命令:

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

答案 10 :(得分:0)

  

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

echo $(</proc/$$/login id). After that, you need to use getent command.

答案 11 :(得分:0)

外壳中(var rootNode = new YamlMappingNode(); rootNode.Add("methods", methods); var result = new YamlDocument(rootNode); var resultStream = new YamlStream(result); using var resultWriter = File.CreateText(@"d:\temp\scraped.yml"); resultStream.Save(resultWriter); ):

3.1.2符号也可以多次使用,作为一种“取消引用”运算符(在C或C ++中为*)

$