回答:
加えて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 ERR
bashの例でまさに起こっていることです。
$ echo $BASHPID
37152
$ ( echo $BASHPID )
18633
マニュアルから:
BASHPID
現在のbashプロセスのプロセスIDに展開されます。これは、
$$
bashを再初期化する必要のないサブシェルなど、特定の状況下とは異なります。
$
シェルのプロセスIDに展開します。で
()
サブシェルは、現在のシェルではなく、サブシェルのプロセスIDに展開されます。
関連:
$BASHPID
変数に保存してサブシェルで使用するように手配しない限り、確実に見つけることができません。はありますが$PPID
、これはシェルのPIDと同じ意味でシェルの親PIDです$$
(サブシェルではリセットされません)。$BASHPPID
変数はありません。
$$
拡張を回避する方法」と「サブシェル内の異なるpid」)。