バックグラウンドプロセスは独自のPIDをどのように知っていますか?

バックグラウンドプロセスは独自のPIDをどのように知っていますか?

私はRH Linuxシステムでbashを使用しています。

通常、$$変数を使用して独自のPIDを取得できます。ただし、スクリプトが独自の機能の1つをバックグラウンドプロセスとして実行している場合、$$を使用すると機能しなくなり、バックグラウンドで実行されるすべての関数は親スクリプトのPIDを取得します。

たとえば、次はテストスクリプトです。

    /tmp/test:
    #!/bin/bash
    echo "I am $$"
    function proce {
      sleep 3
      echo "$1 :: $$"
    }

    for x in aa bb cc; do
      eval "proce $x &"
      echo "Started: $!"
    done

実行時:

    /tmp$ ./test
    I am 5253
    Started: 5254
    Started: 5256
    Started: 5258
    /tmp$ aa :: 5253
    bb :: 5253
    cc :: 5253

したがって、親スクリプト(/ tmp / test)はPID 5253で実行され、PID 5254、5256、および5258で3つのバックグラウンドプロセスを開始します。ただし、これらの各バックグラウンドプロセスは$$で5253の値を取得します。

これらのプロセスは実際のPIDをどのように見つけますか?

答え1

$BASHPIDあなたが探しているものかもしれません。

バッシュPID

現在、BashプロセスのプロセスIDに展開されます。これは、Bashを再初期化する必要がないサブシェルなどの場合によって$ $とは異なります。

相対的な$$

($$) はシェルのプロセス ID に展開されます。 ()サブシェルでは、サブシェルではなく呼び出しシェルのプロセスIDに展開されます。

http://www.gnu.org/software/bash/manual/bashref.html#Bash-変数

答え2

そしてbash

echo "$BASHPID"

echoコマンドを評価したプロセスのpidを提供します。

(例:a以降enable -n echo)プロセスのpidと必ずしも同じである必要はありません。走るそのechoコマンド。

bash(またはすべてのシェル)は、プロセスを介して独自のスープを作成します。どのプロセスが何をしたのかを推測することは必ずしも役に立ちません。

$ readlink -f /proc/self "/proc/$BASHPID"
/proc/30868
/proc/30747
$ (readlink -f /proc/self "/proc/$BASHPID")
/proc/30869
/proc/30869

2番目のケースでは、readlinkコマンドラインを解釈したのと同じプロセスで実行されます。これは、そのサブシェルで実行された最後のコマンドだったためです(したがって、basha最適化fork())。

これに対応する内容はモジュールzshにあります。zsh/system

$ zmodload zsh/system
$ echo $$ $sysparams[pid]
5155 5155
$ (echo $$ $sysparams[pid])
5155 30979

zshサブシェルの親pidも公開されます$sysparams[ppid])。

移植可能な方法は次のとおりです。

pid=$(sh -c 'echo "$PPID"')

すべてのシェルは、shこのコマンドラインを解釈するサブシェルの直接サブシェルとして実行する必要があるため、そのサブシェルである必要がありshます。$PPID

関連情報