回答:
加えて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 が呼び出されたので$pid、と同じになる可能性があります。$$getpid
ksh93。たとえば、の場合はそうではありません。
(...)、のように別のプロセスを生成しない例からのものbashです。
zshまたはyash最適化し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」)。