web-dev-qa-db-ja.com

コマンドラインでbashサブプロセスのプロセスIDを取得する方法

Bashでは、丸括弧()を使用してサブシェルを作成できることを知っています。 bashのmanページによると:

(list) list  is  executed  in  a  subshell environment 

また、現在のプロセスIDを取得するには、次を使用します。

echo $$

今私の質問は、コマンドラインで()を使用して作成されたサブシェルのプロセスIDを取得する方法ですか?

これを使用する場合:

echo $$; ( echo $$; ) 

サブシェルが作成される前でも$$が展開されるため、stdoutで親シェルのプロセスIDが2回出力されますを取得します。では、どのようにして本当に怠惰な拡張を強制するのでしょうか?

[ソリューションはLinuxだけでなくMacでも機能するはずです]

更新:

Macではecho $BASHPID機能しませんなので、提案されたリンクされた回答は機能せず、空白を返します。

30
anubhava

ここで私の質問への答えを見つけることに貴重な時間を費やしてくれた皆さんに感謝します。

ただし、bash ver <4でこのpidを取得するhack方法を見つけたので、今は自分の質問に答えています(すべてのバージョンで機能します)しかし)。コマンドは次のとおりです。

_echo $$; ( F='/tmp/myps'; [ ! -f $F ] && echo 'echo $PPID' > $F; )
_

印刷します:

_5642
13715
_

ここで、13715はサブシェルのpidです。私が行うときにこれをテストするには:

_echo $$; ( F='/tmp/myps'; [ ! -f $F ] && echo 'echo $PPID' > $F; bash $F; ps; )
_

私はこれを得る:

_5642
13773
  PID   TT  STAT      TIME COMMAND
 5642 s001  S      0:02.07 -bash
13773 s001  S+     0:00.00 -bash
_

13773は確かにサブシェルのpidであると私に言っています。

注: @ChrisDoddがecho $$; ( bash -c 'echo $PPID'; )はLinuxで機能しないとコメントしたので、元のソリューションに戻しました。上記の私のソリューションは、MacとLinuxの両方で機能します。

19
anubhava

残念ながら、$ BASHPIDが導入されたbashバージョン4より前では、これを行う簡単な方法はありません。できることの1つは、親PIDを出力する小さなプログラムを作成することです。

int main()
{
    printf("%d\n", getppid());
    return 0;
}

それをppidとしてコンパイルし、パスに配置すると、次のように呼び出すことができます。

$ (echo $$; ppid)
2139
29519
$ (x=$(ppid); echo $x)
29521

しかし、私が気付いた奇妙な点の1つは、

$ (ppid)

実際にはサブシェルで実行されていないようです。bashで実際にサブシェルで実行するには、括弧内に少なくとも2つのコマンドが必要です。

7
Chris Dodd

できるよ :

$ ( your_action ) &
[1] 44012

そして、そのようなサブプロセスのPIDを見つけます:

$ echo "The sub PID : $!"
The Sub PID : 44012

$!バックグラウンドのPIDの最後のジョブを返します。 ( このマニュアル を参照)

4
Zulu

自作を使用してMacにpgrepをインストールします:brew install pgrep

http://mxcl.github.com/homebrew/ をチェックしてHomebrewをインストールしてください。

2
Gerald Boersma

これはうまくいくようです:

(echo $$; echo  `ps axo pid,command,args | grep "$$" |awk '{ getline;print $1}'`)
14609
17365

何らかの理由で、OSXは制限されており、pgrepが付属していません。または、(Linuxで動作する)可能性があります。

 (echo $$; echo  `pgrep -P $$`) 
 14609
 17390
1
masseo

最初にシェルに入ったときに親のppidをエコーアウトすることで、親のBASHPIDを使用できます。その後、プロセスをバックグラウンドで実行し、pidを介して検索できます。 ppidpidを使用します。

例えば。サブシェル内でバックグラウンドで実行されるsleep 555コマンドのpidを取得するには:

(echo "$BASHPID" > /tmp/_tmp_pid_ && sleep 555 &) && ps -ho pid --ppid=$(< /tmp/_tmp_pid_)

1
user4401178