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.
병합됩니다 .ClockService1
ClockService2
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