バックグラウンドシェル機能を使用してサブプロセスリストを取得する

バックグラウンドシェル機能を使用してサブプロセスリストを取得する

バックグラウンドで関数を呼び出すbashスクリプトがあります。

process_manager $1 $2 $3 &

この関数は、引数として渡されたコマンドをバックグラウンドで実行/実行します。

process_manager関数からサブプロセスのリストを取得するには?

私はこれを試みます:

process_manager () {
  count=$1
  interval=$2
  cmd=$3
  bash_pid=$$
  last_pid=$!

  echo "bash_pid: $bash_pid, ppid: $PPID, last_pid: $last_pid"
  $cmd &
  $cmd &
  sleep 30 &
}

process_manager $1 $2 $3 &
process_manager $1 $2 $3 &
process_manager $1 $2 $3 &

しかし、この関数process_managerは最初の呼び出しで$!または$ last_pidを表示しません。

この場合、どのように$last_pidを取得し、サブプロセスのリストにアクセスできますか?

答え1

$$シェルのpidを含みます。処刑された説明するスクリプト。このシェルのすべてのサブシェルで同じです。

$!バックグラウンドで実行される最後のサブコマンドのpidを含みます(&coprocまたはプロセスオーバーライドを使用)。

バックグラウンドで実行されるコマンドでは$!設定されません。$!子プロセスを待機または殺すことができる親プロセス用です。

bash$BASHPIDpidを含む変数があります。現在のサブシェル

それがどのプロセスであるかは必ずしも明確ではありません。

存在する:

echo "$BASHPID"

これはコマンドを解釈したプロセスのpidですがecho

/bin/echo "$BASHPID"

プロセスを分岐しますが、$BASHPID分岐したプロセスのpidを報告するのではなく、親プロセスのpidを報告します。そして:

/bin/echo "$BASHPID" &

(唯一の違いは、親プロセスが子プロセスを待っていないことです。)$BASHPID分岐プロセスのpidを報告します。

$ bash -c 'echo "$$"; echo "$BASHPID"; /bin/echo "$BASHPID"; /bin/echo $BASHPID &'
3264
3264
3264
3266

ただし、お客様の場合は、以下を安全に行うことができます。

process_manager () {
  pid_of_last_command_run_in_background=$!
  mypid=$BASHPID
  cmd &
  cmd1pid=$!
  cmd &
  cmd2pid=$!
}

$pid_of_last_command_run_in_backgroundバックグラウンドで実行される最後のコマンドのpidです(現在のサブシェルまたはその親シェルまたはその祖先によって)。そのため、$last_pid2番目の実行では何か(前のprocess_managerのpid)が得られますが、最初の実行では取得されません。

関連情報