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

관련 정보