- 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어
명령어: ps, grep, wc
키워드: 프로세스, 다중 실행, 허용값
사용처: 정 기적으로 실행되는 명령어의 다중 실행을 감시해서 허용값을 넘으면 경고하고 싶을 때
실행 예제
$ ./process-numcheck.sh
[ERROR] 프로세스 /home/user1/bin/calc 다중 실행 (3)
start alert.sh ...
스크립트
#!/bin/sh
# 감시할 프로세스 명령어와 프로세스 허용수
commname="/home/user1/bin/calc" # ------------------------------------------ 1
threshold=3
# 프로세스 개수 카운트
count=$(ps ax -o command | grep "$commname" | grep -v "^grep" | wc -l) # --- 2
# 프로세스 수가 허용값 이상이면 경고 처리
if [ "$count" -ge "threshold"]; then # if문 --------------------------------- 3
echo "[ERROR] 프로세스 $commname 다중 실행($count)" >&2
/home/user1/bin/alert.sh
fi
해설
이 스크립트는 지정한 프로세스가 다중 실행되지 않았는지 감시합니다. 여기서는 calc 명령어의 실행 수를 감시합니다. 만약 calc 프로그램이 3개 이상 실행되었으면 문제 상황이라고 판단하여 alert.sh를 실행합니다. 여러분은 상황에 맞춰 명령어 이름(셸 변수 commname)을 수정해서 alert.sh로 에러를 표시하거나 메일을 보내는 등에 활용하기 바랍니다.
전제 조건으로 calc라는 프로그램이 5분마다 정기적으로 실행되어 어떤 계산을 하는 배치라고 가정합니다. 이 배치 처리는 두 개까지는 동시 실행되어도 되지만 3개 이상은 서버가 무거워지거나 작업 중 데이터 파손이 일어나는 등의 문제가 발생한다고 가정합니다.
이 calc 명령어를 릴리스했을 당시에는 1회 처리에 10초 정도 걸려서 정기 실행에 아무런 문제가 없었습니다. 하지만 오랫동안 시스템을 운용하다보니 데이터베이스나 로그 파일이 쌓여서 배치 처리 시간이 점점 길어졌다고 합시다.
-
이전보다 서버 부담이 높아져서 곤란해짐
그러다가 calc 명령어 처리 시간이 5분 이상 걸리게 되면 5분 간격 실행으로는 처리가 끝나지 않아서 다중 실행된 프로세스가 쌓이게 되서 서버가 멈추게 될지도 모릅니다.
이런 경우를 방지하고자 프로세스 개수를 감시하는 것이 이 예제입니다. 우선 1 에서 감시할 명령어와 프로세스 허용값을 정의합니다. 짧은 간격에 정기적으로 실행되는 cron에 등록된 배치 처리 등이 대상이 됩니다.
2 에서 ps 명령어를 이용해서 프로세스 개수를 확인합니다. 여기서는 wc 명령어의 -l 옵션을 이용해서 ps 명령어 결과를 grep 명령어로 파이프 처리해서 결과 줄 수를 얻어서 셸 변수 count에 대입합니다. 이것이 지금의 프로세스 수가 됩니다.
3 에서 셸 변수 count와 처음에 정의한 프로세스 개수의 허용값 threshold를 비교합니다. 여기서 test 명령어의 ‘A가 B 이상인지’를 판변하는 연산자 -ge(이상)로 비교합니다. 만약 프로세스 개수가 3 이상이면 허용값을 넘었다고 표시하고 경고 처리 스크립트 alert.sh를 실행합니다. 이렇게 해서 정기적으로 실행되는 명령어의 다중 실행을 확인할 수 있습니다.
앞에서 그림으로 소개한 배치 처리의 중첩은 때로는 데이터 파손 같은 큰 장애를 일으키게 됩니다. 중요한 처리를 할 때는 이런 감시와 함께 잠금 파일 등을 이용해서 처음부터 다중 실행되지 않도록 설계 단계에서 계획하는 것이 좋습니다.
주의사항
-
FreeBSD나 Mac의 wc 명령어 -l 옵션을 이용하면 앞에 스페이스가 들어가 다음처럼 에러 메시지에 필요 없는 공백 문자가 들어갑니다.
- FreeBSD나 Mac인 경우
[ERROR] 프로세스 $commname 다중 실행( 3)
이런 부분이 신경 쓰인다면 “2” 처럼 파이프 처리 마지막에 tr 명령어로 스페이스 삭제 처리를 추가하면 됩니다.
count=$(ps ax -o command | grep "$commname" | grep -v "^grep" | wc -l | tr d ' ')
- 이런 경우와 반대로 프로세스가 다중 실행되는 것이 보통인데, 기준값 이하가 되면 이상 상황이라고 통지하고 싶을 때도 있습니다. 예를 들어 어떤 상주형 데몬 프로그램이 평상시라면 적어도 5개의 프로세스가 있어야 한다면 프로세스가 4개 이하가 되면 문제가 발행했다고 보고해야 할 것입니다. 이럴 때 예제의 “3” 에서 대소 비교 부분을 -ge(이상)를 -le(이하)로 수정하면 대응할 수 있습니다.