bash pid和$$的区别是什么?

23

我是一个Bash脚本的初学者,我有一个"作业"要完成。我已经弄清楚了大部分的东西,但是有一部分说我必须回显父bash进程的pid和我将运行的两个子shell的pid。所以我在网上搜索并找到了这个(Linux文档项目)

#!/bin/bash4

echo "\$\$ outside of subshell = $$"                              # 9602
echo "\$BASH_SUBSHELL  outside of subshell = $BASH_SUBSHELL"      # 0
echo "\$BASHPID outside of subshell = $BASHPID"                   # 9602

echo

( echo "\$\$ inside of subshell = $$"                             # 9602
  echo "\$BASH_SUBSHELL inside of subshell = $BASH_SUBSHELL"      # 1
  echo "\$BASHPID inside of subshell = $BASHPID" )                # 9603
  # Note that $$ returns PID of parent process.

以下是我的问题:

1) 第一个echo打印的是什么?这是父bash的pid吗?

2) 为什么第二个echo打印出0?

3) $BASH_SUBSHELL是一个命令还是一个变量?

4) 我正在使用mac做所有的事情,在未来几天我会在Linux机器上尝试所有这些操作,但是无论何时我运行这个脚本$BASHPID都不会返回任何东西,我只得到一个新的行。这是因为我在mac上运行这个脚本,$BASHPID在mac上不起作用吗?

2个回答

30

查看文档,得知:

  1. $$ 表示脚本文件运行的进程ID。对于任何一个脚本,当它被运行时,它只有一个“主”进程ID。无论你调用多少个子shell,$$ 始终会返回与脚本关联的第一个进程ID。 BASHPID 显示当前bash实例的进程ID,因此在子shell中,它将与“顶级”bash不同,后者可能已经调用了它。
  2. BASH_SUBSHELL 表示您所在的“子shell级别”。如果您不在任何子shell级别中,则您的级别为零。如果您在主程序中启动子shell,则该子shell级别为1。如果您在该子shell中启动子shell,则级别为2,依此类推。
  3. BASH_SUBSHELL 是一个变量。
  4. 也许您使用的bash版本不支持BASHPID?我怀疑这不是“Mac”的问题。

谢谢您的回答并为我澄清这些事情。我发现我有 GNU bash,版本 3.2.48(1)。 - captain
是的,macOS 运行着一个非常老的 bash 版本。 - Noel Yap

7
最好熟悉 bash(1)
   BASHPID
          Expands to the process ID of the current bash process.
          This differs from $$ under certain circumstances, such
          as subshells that do not require bash to be re-
          initialized.
   [...]
   BASH_SUBSHELL
          Incremented by one each time a subshell or subshell
          environment is spawned.  The initial value is 0.

$BASHPID 是在 bash-4.0-alpha 版本中引入的。如果你运行 bash --version 命令,可以查看你正在使用的 bash(1) 版本。

如果你要经常使用 bash(1) ,你还需要以下内容:


所以$ BASHPID对我不起作用,因为我有3.2.48版本。可能需要更新我的bash版本。 - captain
不要升级OS X提供的bash。如果您因某种原因想要一个新版本的bash(1),请确保以这样的方式安装它,以便它不会以任何方式影响系统提供的shell。我不知道bash4与bash3保持了多少向后兼容性,但除非Apple做出了一些努力来保持在POSIX sh(或某些其他受限功能子集)的限制范围内,否则升级版本可能会破坏某些东西。 - sarnold
8
如果你的bash版本中没有$BASHPID,你可以使用export BASHPID=$(sh -c 'echo $PPID')来获取它。 - ACyclic

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