web-dev-qa-db-ja.com

バックグラウンドプロセスはどのようにして自身のPIDを知ることができますか?

RHLinuxシステムで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を発見できますか?

5
Ron

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

BASHPID

現在のBashプロセスのプロセスIDに展開されます。これは、Bashの再初期化を必要としないサブシェルなど、特定の状況下では$$とは異なります。

とは対照的に $$

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

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

9
Devon

bashの場合:

_echo "$BASHPID"
_

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

(たとえば、_enable -n echo_の後)running that echoコマンドであるプロセスのpidと必ずしも同じではないことに注意してください。

bash(または任意のシェル)は、プロセスを使用して独自のスープを作成します。どのプロセスが何をするのかを推測することは必ずしも有用ではありません。

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

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

同等のzshは_zsh/system_モジュールにあります。

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

zshは、_$sysparams[ppid]_のサブシェルの親pidも公開します)。

移植可能に、あなたはすることができます:

_pid=$(sh -c 'echo "$PPID"')
_

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

6