バックグラウンドで関数を呼び出す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
$BASHPID
pidを含む変数があります。現在のサブシェル。
それがどのプロセスであるかは必ずしも明確ではありません。
存在する:
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_pid
2番目の実行では何か(前のprocess_managerのpid)が得られますが、最初の実行では取得されません。