Answers:
除了bash
的$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"
}
请注意,某些外壳程序(例如zsh
或ksh93
)不会为使用(...)
; 创建的每个子外壳程序启动子进程。在这种情况下,$pid
可能最终与相同$$
,这是正确的,因为这getpid
是从中调用的进程的PID 。
ksh93
。
(...)
来自示例的,它可能不会像那样生成单独的进程bash
。
zsh
或yash
优化fork()
子外壳程序中的最后一个命令。如果它是脚本中的最后一个命令,它们甚至可以优化子shell的fork,因此您getpid
甚至可以报告的父项$$
。您可以定义getpid
为:getpid(){ sh -c 'echo "$PPID"'; return; }
禁用以避免出现问题。
exec
不进行优化或不进行优化,则该sh -c ...
进程将是孙子进程,而不是$(...)
使用命令替换的进程的子进程,$PPID
并将成为$(...)
子外壳程序的pid 。这就是上面的set -E
+ trap ERR
bash示例中发生的情况。
$ echo $BASHPID
37152
$ ( echo $BASHPID )
18633
从手册中:
BASHPID
扩展为当前bash进程的进程ID。这与
$$
某些情况下有所不同,例如不需要重新初始化bash的子外壳。
$
扩展为外壳的进程ID。在
()
子外壳程序中,它扩展为当前外壳程序的进程ID,而不是子外壳程序。
有关:
$BASHPID
在变量中并在子外壳中使用它。有$PPID
,但从某种意义上说,它$$
是外壳程序的父PID,与外壳程序的PID 含义相同(它不会在子外壳程序中重置)。没有$BASHPPID
变量。
$$
扩展”与“子外壳中的不同pid”)。