複数のUDPストリームを監視し、それを実行可能データに変換するためにbashスクリプトを設定しました。私の問題は、ストリームキャプチャが実行されているか定期的にチェックし、そうでない場合は再起動するようにスクリプトを設定する必要があることです。
問題は、ストリームのキャプチャごとに新しいプロセス名またはIDを生成し、実行中であることを確認することです。
これは私が持っているものの希釈版です。私が正しい道を行っているかどうか誰かが教えてくれることを願っています。
Subscriber () {
processName="$1$2$4";
echo "$processName";
pgrep $processName;
if [[ $? -ne 0 ]] ; then
echo "Subcription for $1 with IP $2 not found, restarting." ;
while read -re -t 43200 doc; do
<Code to analyze stream>
done < <(bash -c "exec -a $processName <Commands to capture stream as JSON doc>")
else
echo "Subcription for $1 wtih IP $2 found to be running, skipping." ;
fi
}
while read line; do
Subscriber $line;
done < $flatFile
理想的には、exec -aの後にリストされている完全なコマンド文字列のプロセスIDまたは名前を取得したいのですが、現在はやや機能しているように見える最初のコマンドだけを受け入れますが、これは私が望むことをすることを信じていません。する。
flatFileリファレンスは、私が監視している何百ものストリームを一覧表示する動的に更新されるフラットファイルです。
答え1
argv[0]
Linuxのプロセス名は、少なくともプロセスがコマンドを実行するたびに変更されますが、bashが渡すことを許可するのではなく、実行中のファイルのデフォルト名に変更されますexec -a
。
pgrep
引数リスト(スペースで連結)のオプションを一致させることは可能ですが、forと-f
同様に正規表現一致が実行されるため、必要なものと一致するように正規表現を設定する必要があります。grep
pgrep
r
e
argv[0]
または、渡された名前にexec -a
正規表現文字(.
IPv4アドレスでよく使用される文字を含む)が含まれないようにすることもできます。
Subscriber () {
process_arg0="$1$2$4"
# change all regex operators and space to _
process_arg0="${process_arg0//[][ .\\+?\$^()*{\}]/_}"
printf>&2 '%s\n' "$process_arg0"
if ! LC_ALL=C pgrep -f "^$process_arg0( |\$)"; then
printf>&2 '%s\n' "Subscription for $1 with IP $2 not found, restarting."
while IFS= read -r -t 43200 doc; do
<Code to analyze stream>
done < <(
exec -a "$process_arg0" <Commands to capture stream as JSON doc>
)
else
printf>&2 '%s\n' "Subscription for $1 with IP $2 found to be running, skipping."
fi
}
echo
(引用符なしの引用符の使用、意味のない-e
オプション、インタプリタコードに含まれる変数データの欠落など、read
他の顕著なエラーも削除しました。)IFS=
read
それにもかかわらず、名前またはパラメータのリストでプロセスを一致させることは非常に脆弱で危険です。すべてのプロセスが目的の名前またはパラメータのリストを自分で割り当てることができ、ここで使用されているアプローチは競合状態を導入するためです。初期化システム(systemd
、およびco)または、、upstart
などの専用ツールなどの適切なプロセス管理者/管理者を使用する方が適切です。runit
daemontools
supervisor
start-stop-daemon