スクリプトからプロセスの複数のインスタンスPIDを取得して使用します。

スクリプトからプロセスの複数のインスタンスPIDを取得して使用します。

バックグラウンドでw1(ソースコードで)複数のプロセスインスタンスを実行しているとします(無限のwhileループを含む)。while1.cwhile1.c

gcc while1.c -o w1
./w1&
./w1&
./w1&
./w1&

では、各インスタンスのPIDを取得したいと思います。このために私は次のようにしています。

var=$(/bin/ps r -o pid,cmd|grep "w1"| grep -v "grep"|awk '{print $1}')

w1これは、すべてのインスタンスのPIDを保存します$var
その場合は、次のようにしてください。

echo $var

すべてのインスタンスのPIDを印刷しますw1

しかし、個々のPIDにアクセスしたいです。つまり:

echo ${var[0]}
echo ${var[1]}

など(配列など)。どうすればいいですか?

PS:echo ${var[0]}すべてのPIDが印刷されますが、echo ${var[1]}その他echo ${var[2]}は何も印刷しません(出力の空白行など)。

答え1

プロセスの開始時に PID を保存します。

pids=()

./w1 & pids+=( "$!" )
./w1 & pids+=( "$!" )
./w1 & pids+=( "$!" )
./w1 & pids+=( "$!" )

(シェルにbash互換性のある配列構文があると仮定)

これで配列にPIDがあり、背中からpidsアクセスできます。"${pids[0]}""${pids[1]}"

一般を使用する場合/bin/sh

set --

./w1 & set -- "$@" "$!"
./w1 & set -- "$@" "$!"
./w1 & set -- "$@" "$!"
./w1 & set -- "$@" "$!"

今、あなたのPIDはリストにあり、背中から"$@"アクセスすることができます。"$1""$2"

この特殊値は、"$!"最後に開始されたバックグラウンドコマンドのPIDになります。

答え2

Bashを実行している場合はこれを使用できjobs -l、バックグラウンドジョブとそのPIDが一覧表示されます。たとえば、次のコマンドは、一致するすべてのジョブのPIDを./w1配列に保存しますpids

pids=( $(jobs -l | awk '/\.\/w1/ {print $2}') )

他のシェルでは、これを使用してps --ppid $$現在のシェルを親に持つすべてのアクションを一覧表示できます。

pids=( $(ps --ppid $$ -o pid,cmd -h | awk '/\.\/w1/ {print $1}') )

注:私が知っている限り、これは移植性がなく、psLinuxprocpsパッケージでのみ利用可能です。他のバージョンにはps同じオプションはありません。

FreeBSDを使用すると、ps次のことができます(bash、ksh、または他の配列認識シェルから):

pids=( $(ps -j | awk -v ppid=$$ '$3==ppid && /\.\/w1/ {print $2}') )

時間があれば、pgrep次のものを使用できます。

pids=( $(pgrep -P $$ w1) )

すべてのバリアントでバックグラウンドプロセスが一致していることを確認してください./w1。 PPIDが他のサブプロセスやバックグラウンドプロセスを決して実行しないと確信している場合は、スクリプトでそのテストをスキップできます(そして2番目のバリアント本文のコマンドにawk出力が必要です)。-o pidps

関連情報