バックグラウンドでw1
(ソースコードで)複数のプロセスインスタンスを実行しているとします(無限のwhileループを含む)。while1.c
while1.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}') )
注:私が知っている限り、これは移植性がなく、ps
Linuxprocps
パッケージでのみ利用可能です。他のバージョンには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 pid
ps