如何获取子shell的pid?

如何获取子shell的pid?

如何获取子shell的pid?

例如:

$ echo $$
16808

这不起作用,因为原始外壳会扩展$$

$ ( echo $$ )
16808

为什么单引号不起作用?原shell去掉单引号后,子shell$$本身不展开吗?

$ ( echo '$$' )
$$

为什么eval也不起作用?是eval由子shell运行的吗?为什么它给我原始 shell 的 PID?

$ ( eval echo '$$' )
16808

谢谢。

答案1

$ echo $BASHPID
37152
$ ( echo $BASHPID )
18633

从手册中:

BASHPID

扩展为当前 bash 进程的进程 ID。这与$$某些情况下不同,例如不需要重新初始化 bash 的子 shell。

$

扩展为 shell 的进程 ID。在()子 shell 中,它扩展为当前 shell 的进程 ID,而不是子 shell。

有关的:

答案2

除了bashs之外$BASHPID,您还可以使用以下方法进行移植:

pid=$(exec sh -c 'echo "$PPID"')

例子:

(pid=$(exec sh -c 'echo "$PPID"'); echo "$$ $pid")

您可以将其变成一个函数:

# usage getpid [varname]
getpid(){
    pid=$(exec sh -c 'echo "$PPID"')
    test "$1" && eval "$1=\$pid"
}

请注意,某些 shell(例如zshksh93)不会为使用 ; 创建的每个子 shell 启动子进程(...)。在这种情况下,$pid最终可能与 相同,这是正确的,因为这是调用$$进程的 PID 。getpid

答案3

在 Linux 上,不生成新进程的跨 shell 解决方案(至少是 dash、bash、zsh)是

read -r this_pid < /proc/self/stat; echo ${this_pid%% *}

至少在 bash 和 zsh 中我们还可以使用空格作为读取分隔符:

read -d ' ' this_pid < /proc/self/stat ; echo $this_pid

也可以看看人5过程 /proc/[pid]/stat 节

答案4

要回答最初的“为什么”问题 - 为什么不$$扩展到子shell pid,甚至懒惰地评估eval

引用POSIX 文档:

$

扩展为所调用 shell 的十进制进程 ID。在子 shell 中(请参阅 Shell 执行环境),“$”应扩展为与当前 shell 相同的值。

相关内容