BASH - シーケンス/増加する数値を含むgrep psデータ

BASH - シーケンス/増加する数値を含むgrep psデータ

psのプロセスリストを繰り返すbash forループがあります。アイデアは、プロセスが実行中であることを確認し、出力を計算することです。以下は、繰り返す例のリストです。

BOX.Container_Philips1_Primary_X1
BOX.Container_Philips_Primary_X1
BOX.Container_Philips3_Primary_X1
BOX.Container_Server1_X1
BOX.Container_Node1_X1
BOX.Container_Host1_X1
BOX.Container_ClockService1_X1
BOX.Container_ClockService2_X1

私のbashコードは次のとおりです

#PSUEDO
procs=(
Philips 1
Node 1 
Host 1 
Server 1
Philips1 1
Philips3 1 
ClockService 2)
#END PSUEDO

for (( i=0 ; i<"${#procs[@]}" ; i++ ))
do
  name=$(echo "${procs[i]}" | awk '{print $1}')
  configured_count=$(echo "${procs[i]}" | awk '{print $2}')

  running=()
  while read -r line
  do
    running+=("${line}")
  done < <(ps -u user -f | grep "BOX.${name}" | grep -v grep)

  if [[ "${configured_count}" -gt "${#running[@]}" ]]; then
    result+=$(echo -e "\n[FAIL] ${name} - configured count: ${configured_count} running count: ${#running[@]}")
  elif [[ "${#running[@]}" -gt "${configured_count}" ]]; then
    result+=$(echo -e "\n[WARN] ${name} - configured count: ${configured_count} running count: ${#running[@]}")
  else
    result+=$(echo -e "\n[PASS] ${name} - configured count: ${configured_count} running count: ${#running[@]}")
  fi
done

繰り返すと、name = Philipsは3つ(エラー)を返し、name = Philips1またはPhilips3は1つ(必須)を返します。 Philipsラインの処理方法についていくつかのアイデアが必要ですが、「ホスト」、「ノード」の項目を誤って計算しないでください。アーキテクチャの観点からは、Philipsプロセスは異なりますが、ClockServiceはロードバランシングされます。 ClockServiceの個数は2個ですが、各Philipsの個数は1個でなければならないと言いたいです。

答え1

grep必要なものとより密接に一致するスキーマを構築することがアイデアです。.すべての文字と一致する必要があることを忘れないでください。

たとえば、BOX.Container_${name}_便利なパターンになります。これPhilipsとは異なり、Philips1アイテムをマージしたい場所を検索できます。これにより合計がClockService.マージされます。ClockService1ClockService2

grep -c[B]OXまた、この要件を回避するために、いくつかのテストを簡素化するために使用して使用することもできますgrep -v

したがって、生成されたコードは次のようになります。

declare -A procs=(
[Philips]=1
[Node.]=1 
[Host.]=1 
[Server.]=1
[Philips1]=1
[Philips3]=1 
[ClockService.]=2)

# psout=$(ps -u user -f)
psout=$(cat psout)

for i in "${!procs[@]}"
do
  name=$i
  configured_count=${procs[$i]}

  running=$(echo "$psout" | grep -c "[B]OX.Container_${name}_")

  if [[ "$configured_count" -gt "$running" ]]; then
    result+=$(echo -e "\n[FAIL] ${name} - configured count: ${configured_count} running count: $running")
  elif [[ "$running" -gt "$configured_count" ]]; then
    result+=$(echo -e "\n[WARN] ${name} - configured count: ${configured_count} running count: $running")
  else
    result+=$(echo -e "\n[PASS] ${name} - configured count: ${configured_count} running count: $running")
  fi
done

echo "$result"

この例では、をcat呼び出すのではなくファイルに影響しますが、psそれを変更する方法を確認できます。

% cat psout
BOX.Container_Philips1_Primary_X1
BOX.Container_Philips_Primary_X1
BOX.Container_Philips3_Primary_X1
BOX.Container_Server1_X1
BOX.Container_Node1_X1
BOX.Container_Host1_X1
BOX.Container_ClockService1_X1
BOX.Container_ClockService2_X1

% bash code

[PASS] Node. - configured count: 1 running count: 1
[PASS] ClockService. - configured count: 2 running count: 2
[PASS] Philips1 - configured count: 1 running count: 1
[PASS] Philips3 - configured count: 1 running count: 1
[PASS] Server. - configured count: 1 running count: 1
[PASS] Philips - configured count: 1 running count: 1
[PASS] Host. - configured count: 1 running count: 1

答え2

皆様のご意見やご意見ありがとうございます。私が言及していない入力のもう一つの要素は、プロセスの種類を区別するだけの単純な「BOX」ではなく接頭辞です。 ps入力例

BOX.CC_Container_Philips1_Primary_X1
BOX.CC_Container_Philips_Primary_X1
BOX.CC_Container_Philips3_Primary_X1
BOX.Container_Server1_X1
BOX.Container_Node1_X1
BOX.Container_Host1_X1
BOX.Container_ClockService1_X1
BOX.Container_ClockService2_X1

だから私がしたことは、タイプ(「CC」ですか?)に基づいて条件文を作成し、それに対して別々のループを実行することでした。おそらく最善のアプローチではありませんが、うまくいきます。

#name = list of process names from SQL, parsed into an array
type=$(echo "${name}" | awk -F"_" '{print $1}')
if [[ "${type}" == "CC" ]]; then
while read -r line
do
  running+=("${line}")
done < <(ps -u esmadmin -f | grep "${DOMAIN}.${name}_" | grep -v grep)
else 
  while read -r line
  do
  running+=("${line}")
done < <(ps -u esmadmin -f | grep "${DOMAIN}.${name}" | grep -v grep)
fi

関連情報