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 ERRbash示例中发生的情况。
$ echo $BASHPID
37152
$ ( echo $BASHPID )
18633
从手册中:
BASHPID扩展为当前bash进程的进程ID。这与
$$某些情况下有所不同,例如不需要重新初始化bash的子外壳。
$扩展为外壳的进程ID。在
()子外壳程序中,它扩展为当前外壳程序的进程ID,而不是子外壳程序。
有关:
$BASHPID在变量中并在子外壳中使用它。有$PPID,但从某种意义上说,它$$是外壳程序的父PID,与外壳程序的PID 含义相同(它不会在子外壳程序中重置)。没有$BASHPPID变量。
$$扩展”与“子外壳中的不同pid”)。