배포 전마다 여러 서버의 DB, Redis, API 포트를 사람이 손으로 확인합니다. 어느 날 한 포트를 빼먹어 장애가 났고, 체크리스트는 있었지만 자동 증거는 없었습니다.
반복 점검은 스크립트로 남겨야 합니다. 성공과 실패를 같은 형식으로 기록하면 장애 전후 비교가 쉬워집니다.
네트워크 통신 점검 쉘 스크립트
"어젯밤에 DB 연결이 잠깐 끊겼는데 언제 어느 서버인지 모르겠다."
자동화된 점검 스크립트가 있다면 이런 문제를 사전에 감지하고 기록할 수 있습니다.
이 챕터에서는 nc와 bash를 활용해 여러 서버의 포트 통신을 자동 점검하는
스크립트를 단계적으로 완성합니다.
1. 핵심 도구와 개념
- 1nc -zv -w 옵션과 종료 코드($?)를 이용한 포트 점검 원리
- 2타임스탬프 로그 기록과 bash 배열 루프 활용
- 3단일 포트 점검에서 다중 서버 배열 루프 점검으로 확장
- 4crontab 주기 표현식과 자동 실행 등록
- 5장애 감지 시 슬랙·이메일 알림 연동
- 6cron 환경 PATH 문제와 스크립트 실행 권한 트러블슈팅
which ncmkdir -p /opt/scriptssystemctl status crond || systemctl status cronls -la /var/log/netcheck.log 2>/dev/null || echo '로그 없음 (첫 실행 후 생성됨)'nc(netcat)와 종료 코드($?)를 이용한 포트 점검
매일 아침 출근하면 외부 API 연동 서비스가 죽어있습니다. 새벽에 외부 포트가 일시적으로 막혔다가 복구됐지만 서비스는 재시작되지 않은 것입니다. 이런 상황을 자동으로 감지하고 알람을 보내려면 포트 점검 스크립트가 필요합니다. nc의 종료 코드를 활용하면 조건 분기 없이 포트 열림/닫힘을 판별하는 스크립트를 깔끔하게 만들 수 있습니다.

네트워크 점검 스크립트의 핵심은 nc의 종료 코드를 활용하는 것입니다.
nc -zv -w 옵션 설명
# 실습 디렉토리 준비
mkdir -p /tmp/networking/part6/exam_32 && cd /tmp/networking/part6/exam_32
nc -zv -w 3 192.168.1.200 3306
- 핵심 출력—명령 결과에서 성공/실패를 가르는 값을 먼저 확인합니다
- 대상 식별—IP, 포트, 인터페이스, 프로세스명처럼 다음 조치를 결정하는 필드를 봅니다
- 다음 분기—결과가 기대와 다르면 어느 계층을 이어서 점검할지 정합니다
| 옵션 | 의미 |
|---|---|
-z | 데이터 전송 없이 연결 가능 여부만 확인 (zero I/O) |
-v | 상세 출력 (verbose) |
-w 3 | 연결 타임아웃 3초 (wait) |
종료 코드($?)로 성공/실패 판단
# 포트 점검 후 종료 코드 확인
nc -zv -w 3 192.168.1.200 3306
echo $?
# 0 → 연결 성공 (포트 열려 있음)
# 1 → 연결 실패 (포트 닫힘, 방화벽 차단, 서버 다운 등)
if문과 결합
nc -zv -w 3 192.168.1.200 3306 2>/dev/null
if [ $? -eq 0 ]; then
echo "SUCCESS: DB 포트 정상"
else
echo "FAIL: DB 포트 응답 없음"
fi
# 축약 표현 (더 일반적)
if nc -zv -w 3 192.168.1.200 3306 2>/dev/null; then
echo "SUCCESS"
else
echo "FAIL"
fi
2>/dev/null 의미
nc -v는 상세 메시지를 stderr(2)로 출력합니다.
2>/dev/null은 stderr를 /dev/null로 버려서 화면 출력을 억제합니다.
스크립트 로그에는 직접 작성한 메시지만 남도록 할 때 유용합니다.
타임스탬프 로그와 배열 루프
포트 점검 스크립트가 실패했습니다. 그런데 언제 실패했는지 로그에 시간이 없어서 새벽 3시에 발생한 장애인지 아침 9시에 발생한 건지 알 수 없습니다. 또 점검 대상이 늘어날수록 서버 목록을 일일이 하드코딩해야 합니다. 타임스탬프 로깅과 배열 루프를 활용하면 스크립트를 실무에서 실제로 쓸 수 있는 수준으로 만들 수 있습니다.
타임스탬프 기록
# date 명령으로 현재 시각 형식 지정
date '+%Y-%m-%d %H:%M:%S'
# 출력: 2024-01-15 14:30:25
# 변수에 저장
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$TIMESTAMP] 점검 시작"
# 로그 파일에 기록 (>>: 이어쓰기, >: 덮어쓰기)
echo "[$TIMESTAMP] 포트 점검 결과" >> /var/log/netcheck.log
배열 선언과 루프
# bash 배열 선언
SERVERS=("192.168.1.100" "192.168.1.200" "192.168.1.201")
PORTS=(3306 6379 8080)
# 배열 순회
for server in "${SERVERS[@]}"; do
echo "점검 중: $server"
done
# 인덱스와 함께 순회
for i in "${!SERVERS[@]}"; do
echo "서버 $i: ${SERVERS[$i]}"
done
# 배열 길이
echo "서버 수: ${#SERVERS[@]}"
로그 파일 관리
LOG_FILE="/var/log/netcheck.log"
# 로그 디렉터리 생성 (없으면)
mkdir -p $(dirname $LOG_FILE)
# 로그 크기 제한 (7일 이상 된 항목 삭제)
find /var/log/ -name "netcheck*.log" -mtime +7 -delete
# logrotate 설정 파일 예시
# /etc/logrotate.d/netcheck
# /var/log/netcheck.log {
# daily
# rotate 7
# compress
# missingok
# notifempty
# }
2. 기본 5줄 점검 스크립트
쉘 스크립트 작성 시 필수적인 Bash 리스트 핸들링과 logger 활용
네트워크 점검 자동화 스크립트를 작성할 때 다수의 호스트 IP를 일괄 루프로 돌리기 위해 SRE는 다음과 같은 문법적 디테일을 준수해야 합니다.
- 올바른 Bash 1차원 배열 선언:
SERVERS=("192.168.1.100" "192.168.1.200")- 공백으로 항목을 구분하고 소괄호
()로 감싸 선언해야 루프 내부에서 정상 순회합니다. SERVERS=["192.168.1.100", "192.168.1.200"](파이썬/JS 리스트 표기법) 또는SERVERS:192.168.1.100,192.168.1.200등은 문법 오류를 일으키며, 오직SERVERS=("값1" "값2")처럼 소괄호 구조만 정상 인식합니다.
- 공백으로 항목을 구분하고 소괄호
- logger 명령어를 통한 시스템 로그 수집:
스크립트 진단 결과나 타임스탬프가 가미된 경고 메시지를 로컬 파일 외에 시스템 표준 중앙 로그 데몬에 전송할 때는
logger명령어를 사용해/var/log/syslog(또는/var/log/messages)에 영구 기록시킵니다.로컬 터미널# 시스템 syslog에 실시간 네트워크 진단 경고 기록 $ logger "SYSTEM-ALERT: Network ping check failed for database server!"
쉘 스크립트 작성 시 필수적인 Bash 리스트 핸들링과 logger 활용
네트워크 점검 자동화 스크립트를 작성할 때 다수의 호스트 IP를 일괄 루프로 돌리기 위해 SRE는 다음과 같은 문법적 디테일을 준수해야 합니다.
- 올바른 Bash 1차원 배열 선언:
SERVERS=("192.168.1.100" "192.168.1.200")- 공백으로 항목을 구분하고 소괄호
()로 감싸 선언해야 루프 내부에서 정상 순회합니다. SERVERS=["192.168.1.100", "192.168.1.200"](파이썬/JS 리스트 표기법) 또는SERVERS:192.168.1.100,192.168.1.200등은 문법 오류를 일으키며, 오직SERVERS=("값1" "값2")처럼 소괄호 구조만 정상 인식합니다.
- 공백으로 항목을 구분하고 소괄호
- logger 명령어를 통한 시스템 로그 수집:
스크립트 진단 결과나 타임스탬프가 가미된 경고 메시지를 로컬 파일 외에 시스템 표준 중앙 로그 데몬에 전송할 때는
logger명령어를 사용해/var/log/syslog(또는/var/log/messages)에 영구 기록시킵니다.로컬 터미널# 시스템 syslog에 실시간 네트워크 진단 경고 기록 $ logger "SYSTEM-ALERT: Network ping check failed for database server!"
쉘 스크립트 작성 시 필수적인 Bash 리스트 핸들링과 logger 활용
네트워크 점검 자동화 스크립트를 작성할 때 다수의 호스트 IP를 일괄 루프로 돌리기 위해 SRE는 다음과 같은 문법적 디테일을 준수해야 합니다.
- 올바른 Bash 1차원 배열 선언:
SERVERS=("192.168.1.100" "192.168.1.200")- 공백으로 항목을 구분하고 소괄호
()로 감싸 선언해야 루프 내부에서 정상 순회합니다. SERVERS=["값1", "값2"](파이썬/JS 리스트 표기법) 또는SERVERS:192.168.1.100...등은 Bash에서 문법 오류를 일으킵니다.
- 공백으로 항목을 구분하고 소괄호
- logger 명령어를 통한 시스템 로그 수집:
스크립트 진단 결과나 타임스탬프가 가미된 경고 메시지를 로컬 파일 외에 시스템 표준 중앙 로그 데몬에 전송할 때는
logger명령어를 사용해/var/log/syslog(또는/var/log/messages)에 영구 기록시킵니다.로컬 터미널# 시스템 syslog에 실시간 네트워크 진단 경고 기록 $ logger "SYSTEM-ALERT: Network ping check failed for database server!"
mkdir -p /tmp/networking/part6/scripts && cd /tmp/networking/part6/scripts
cat > targets.txt << 'EOF'
8.8.8.8 Google DNS
1.1.1.1 Cloudflare DNS
192.168.1.1 Gateway
EOF
cat > check_base.sh << 'EOF'
#!/bin/bash
# 네트워크 점검 기본 템플릿
TARGETS_FILE="${1:-targets.txt}"
LOG_FILE="network_check_$(date +%Y%m%d_%H%M%S).log"
check_host() {
local ip="$1"
local name="$2"
if ping -c 1 -W 2 "$ip" &>/dev/null; then
echo "✓ $name ($ip): reachable"
else
echo "✗ $name ($ip): UNREACHABLE"
fi
}
echo "=== Network Check $(date) ===" | tee "$LOG_FILE"
while read -r ip name; do
check_host "$ip" "$name" | tee -a "$LOG_FILE"
done < "$TARGETS_FILE"
EOF
chmod +x check_base.sh
먼저 가장 단순한 형태의 포트 점검 스크립트를 작성합니다.
#!/bin/bash
# 파일: /opt/scripts/netcheck-simple.sh
# 기본 5줄 포트 점검 스크립트
TARGET_HOST="192.168.1.200"
TARGET_PORT="3306"
LOG_FILE="/var/log/netcheck.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
nc -zv -w 3 "$TARGET_HOST" "$TARGET_PORT" 2>/dev/null \
&& echo "[$TIMESTAMP] OK ${TARGET_HOST}:${TARGET_PORT}" >> "$LOG_FILE" \
|| echo "[$TIMESTAMP] FAIL ${TARGET_HOST}:${TARGET_PORT}" >> "$LOG_FILE"
실행 권한 부여 및 테스트
chmod +x /opt/scripts/netcheck-simple.sh
# 직접 실행
/opt/scripts/netcheck-simple.sh
# 로그 확인
cat /var/log/netcheck.log
# [2024-01-15 14:30:25] OK 192.168.1.200:3306
# [2024-01-15 14:35:25] FAIL 192.168.1.200:3306 ← 장애 발생 시
&& 와 || 연산자 이해
명령A && 명령B # 명령A가 성공(0)일 때만 명령B 실행
명령A || 명령B # 명령A가 실패(non-0)일 때만 명령B 실행
# nc 성공 → && 이후 OK 기록
# nc 실패 → || 이후 FAIL 기록
여러 서버와 포트를 배열로 관리하는 확장 버전을 작성합니다.
#!/bin/bash
# 파일: /opt/scripts/netcheck.sh
# 다중 서버 포트 점검 스크립트
LOG_FILE="/var/log/netcheck.log"
TIMEOUT=3
# 점검 대상: "호스트:포트:설명" 형식
TARGETS=(
"192.168.1.200:3306:MySQL-DB"
"192.168.1.200:6379:Redis-Cache"
"192.168.1.100:8080:App-Server"
"192.168.1.100:80:Nginx"
"10.0.0.10:5432:PostgreSQL"
)
# 로그 디렉터리 생성
mkdir -p $(dirname "$LOG_FILE")
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
FAIL_COUNT=0
echo "[$TIMESTAMP] ===== 네트워크 점검 시작 =====" >> "$LOG_FILE"
for target in "${TARGETS[@]}"; do
# "호스트:포트:설명" 파싱
HOST=$(echo "$target" | cut -d: -f1)
PORT=$(echo "$target" | cut -d: -f2)
DESC=$(echo "$target" | cut -d: -f3)
# 포트 점검
if nc -zv -w "$TIMEOUT" "$HOST" "$PORT" 2>/dev/null; then
echo "[$TIMESTAMP] OK ${HOST}:${PORT} (${DESC})" >> "$LOG_FILE"
else
echo "[$TIMESTAMP] FAIL ${HOST}:${PORT} (${DESC})" >> "$LOG_FILE"
FAIL_COUNT=$((FAIL_COUNT + 1))
fi
done
echo "[$TIMESTAMP] ===== 점검 완료 (실패: ${FAIL_COUNT}건) =====" >> "$LOG_FILE"
# 실패가 있으면 비정상 종료 코드 반환 (cron에서 메일 발송 트리거 가능)
exit $FAIL_COUNT
실행 및 로그 확인
chmod +x /opt/scripts/netcheck.sh
/opt/scripts/netcheck.sh
# 로그 확인
tail -20 /var/log/netcheck.log
# [2024-01-15 14:30:00] ===== 네트워크 점검 시작 =====
# [2024-01-15 14:30:00] OK 192.168.1.200:3306 (MySQL-DB)
# [2024-01-15 14:30:00] OK 192.168.1.200:6379 (Redis-Cache)
# [2024-01-15 14:30:00] FAIL 192.168.1.100:8080 (App-Server)
# [2024-01-15 14:30:00] OK 192.168.1.100:80 (Nginx)
# [2024-01-15 14:30:00] FAIL 10.0.0.10:5432 (PostgreSQL)
# [2024-01-15 14:30:00] ===== 점검 완료 (실패: 2건) =====
5분마다 자동으로 점검이 실행되도록 cron에 등록합니다.
# crontab 편집
crontab -e
# 다음 내용 추가:
# 5분마다 점검 스크립트 실행
*/5 * * * * /opt/scripts/netcheck.sh
# 매시간 정각에 실행
# 0 * * * * /opt/scripts/netcheck.sh
# 매일 오전 9시에 실행
# 0 9 * * * /opt/scripts/netcheck.sh
cron 표현식 이해
*/5 * * * * 명령
│ │ │ │ └── 요일 (0-7, 0과 7은 일요일)
│ │ │ └──── 월 (1-12)
│ │ └────── 일 (1-31)
│ └──────── 시 (0-23)
└──────────── 분 (0-59)
*/5 = 5의 배수 분마다 (0, 5, 10, 15 ...)
cron 등록 후 확인
# 현재 crontab 확인
crontab -l
# */5 * * * * /opt/scripts/netcheck.sh
# cron 서비스 상태 확인
systemctl status crond # CentOS
systemctl status cron # Ubuntu
# cron 실행 로그 확인
grep netcheck /var/log/cron # CentOS
grep netcheck /var/log/syslog # Ubuntu
journalctl -u cron | grep netcheck # systemd 환경
cron 실행 환경 주의사항
# cron은 PATH가 제한되어 있어 전체 경로 사용 필수
# /etc/nc → nc 대신 /usr/bin/nc 또는 /bin/nc
which nc # nc의 전체 경로 확인
# 스크립트 상단에 PATH 명시하거나 스크립트 내에서 절대 경로 사용
NC=/usr/bin/nc
$NC -zv -w 3 "$HOST" "$PORT"
장애 감지 시 즉시 알림이 가도록 스크립트를 확장합니다.
#!/bin/bash
# 파일: /opt/scripts/netcheck-alert.sh
# 장애 감지 시 알림 포함 버전
LOG_FILE="/var/log/netcheck.log"
TIMEOUT=3
SLACK_WEBHOOK="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
ALERT_EMAIL="ops-team@company.com"
TARGETS=(
"192.168.1.200:3306:MySQL-DB"
"192.168.1.200:6379:Redis-Cache"
"192.168.1.100:8080:App-Server"
)
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
HOSTNAME=$(hostname)
FAILED_SERVICES=""
for target in "${TARGETS[@]}"; do
HOST=$(echo "$target" | cut -d: -f1)
PORT=$(echo "$target" | cut -d: -f2)
DESC=$(echo "$target" | cut -d: -f3)
if nc -zv -w "$TIMEOUT" "$HOST" "$PORT" 2>/dev/null; then
echo "[$TIMESTAMP] OK ${HOST}:${PORT} (${DESC})" >> "$LOG_FILE"
else
echo "[$TIMESTAMP] FAIL ${HOST}:${PORT} (${DESC})" >> "$LOG_FILE"
FAILED_SERVICES="${FAILED_SERVICES}\n- ${DESC} (${HOST}:${PORT})"
fi
done
# 장애 발생 시 알림
if [ -n "$FAILED_SERVICES" ]; then
ALERT_MSG="[$HOSTNAME] 네트워크 장애 감지 (${TIMESTAMP}):\n${FAILED_SERVICES}"
# 슬랙 알림
if command -v curl &>/dev/null; then
curl -s -X POST "$SLACK_WEBHOOK" \
-H 'Content-type: application/json' \
--data "{\"text\":\"$ALERT_MSG\"}" > /dev/null
fi
# 이메일 알림 (mailx 필요)
if command -v mail &>/dev/null; then
echo -e "$ALERT_MSG" | mail -s "[ALERT] 네트워크 장애 감지" "$ALERT_EMAIL"
fi
fi
3. 장애 사례 분석
증상
/opt/scripts/netcheck.sh
# [2024-01-15 14:30:00] 점검 시작
# [2024-01-15 14:30:00] OK 192.168.1.200:3306 (MySQL-DB)
# (여기서 스크립트가 수 분 동안 멈춤...)
원인 분석
-w 타임아웃 옵션 없이 nc를 사용하면,
방화벽이 패킷을 DROP하는 서버에 대해 기본 타임아웃(수십 초)만큼 대기합니다.
# 잘못된 예 — 타임아웃 없음
nc -zv 192.168.1.201 3306 # DROP 구간에서 멈춤
# 올바른 예 — 3초 타임아웃
nc -zv -w 3 192.168.1.201 3306
스크립트 실행 시간 측정
# 타임아웃 없이 5개 서버 점검 시
# → 각 DROP 서버에서 ~30초 × 5 = 150초 소요
# -w 3 설정 시
# → 각 DROP 서버에서 3초 × 5 = 15초 소요
# → 10배 빠른 점검 완료
수정 후 스크립트
# TIMEOUT 변수를 환경에 맞게 조정
TIMEOUT=3 # 내부망: 3초, 인터넷 구간: 5-10초
nc -zv -w "$TIMEOUT" "$HOST" "$PORT" 2>/dev/null
교훈: 네트워크 점검 스크립트에서 -w(타임아웃)는 선택이 아닌 필수입니다.
cron에서 실행되는 스크립트가 멈추면 다음 실행 시 겹쳐서 프로세스가 쌓입니다.
증상
# crontab에 등록했는데 로그가 쌓이지 않음
crontab -l
# */5 * * * * /opt/scripts/netcheck.sh
# 5분 후에도 /var/log/netcheck.log 변화 없음
원인 확인 및 해결
이 명령은 실행 중인 서비스 상태를 바꿔 순간적인 중단이나 설정 반영 실패를 만들 수 있습니다. 운영 트래픽 영향과 재시작 후 확인 명령을 먼저 준비하세요.
# [원인 1] 실행 권한 없음
ls -la /opt/scripts/netcheck.sh
# -rw-r--r-- 1 root root ... ← 실행 권한 없음!
# 해결
chmod +x /opt/scripts/netcheck.sh
# [원인 2] cron 서비스 미실행
systemctl status crond
# inactive (dead)
# 해결
systemctl start crond
systemctl enable crond
# [원인 3] nc가 cron 환경 PATH에 없음
# cron은 /usr/bin:/bin 정도만 PATH에 포함
# 스크립트 첫 줄에 PATH 추가
head -3 /opt/scripts/netcheck.sh
#!/bin/bash
export PATH=/usr/bin:/bin:/usr/local/bin:$PATH
# ...
# [원인 4] cron 실행 오류 로그 확인
grep CRON /var/log/syslog | tail -20 # Ubuntu
journalctl -u crond | tail -20 # CentOS systemd
# [원인 5] cron 출력을 파일로 리다이렉션
# crontab 항목에 출력 리다이렉션 추가
# */5 * * * * /opt/scripts/netcheck.sh >> /var/log/netcheck-cron.log 2>&1
cron 디버깅 팁
# cron 환경에서 수동 테스트
env -i HOME=/root SHELL=/bin/bash /bin/bash /opt/scripts/netcheck.sh
# 이렇게 실행해서 오류가 나면 cron에서도 동일하게 오류 발생
교훈: cron 등록 후 반드시 실제로 실행되는지 로그로 확인하세요. 실행 권한, PATH, cron 서비스 상태를 순서대로 점검합니다.
4. 실무 현장 관점
실무에서 이 스크립트가 필요한 순간
-
정기 배포/패치 후 확인: 배포 후 모든 서비스 간 연결이 정상인지 자동으로 확인하는 스모크 테스트로 활용
-
24시간 모니터링: 모니터링 도구(Zabbix, Prometheus 등)가 없는 소규모 환경에서 간단한 가용성 모니터링 역할
-
장애 보고서 근거: 장애 발생 시 정확한 시각과 영향 받은 서버를 로그 파일에서 바로 확인 가능
완성된 프로덕션 수준 스크립트
#!/bin/bash
# /opt/scripts/netcheck-production.sh
# 프로덕션 수준 네트워크 점검 스크립트
set -euo pipefail
# === 설정 ===
LOG_FILE="/var/log/netcheck.log"
LOG_MAX_DAYS=30
TIMEOUT=3
HOSTNAME=$(hostname -f)
# === 점검 대상 (환경에 맞게 수정) ===
TARGETS=(
"db-primary.internal:3306:MySQL-Primary"
"db-replica.internal:3306:MySQL-Replica"
"cache.internal:6379:Redis"
"app1.internal:8080:App-Server-1"
"app2.internal:8080:App-Server-2"
"lb.internal:80:Load-Balancer"
)
# === 함수 정의 ===
log() {
local level=$1
shift
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $*" >> "$LOG_FILE"
}
check_port() {
local host=$1
local port=$2
nc -zv -w "$TIMEOUT" "$host" "$port" 2>/dev/null
return $?
}
cleanup_old_logs() {
find "$(dirname "$LOG_FILE")" -name "netcheck*.log" -mtime +"$LOG_MAX_DAYS" -delete 2>/dev/null
}
# === 메인 로직 ===
mkdir -p "$(dirname "$LOG_FILE")"
cleanup_old_logs
FAIL_COUNT=0
FAIL_LIST=""
log "INFO" "=== 점검 시작 (호스트: $HOSTNAME, 대상: ${#TARGETS[@]}개) ==="
for target in "${TARGETS[@]}"; do
HOST=$(echo "$target" | cut -d: -f1)
PORT=$(echo "$target" | cut -d: -f2)
DESC=$(echo "$target" | cut -d: -f3)
if check_port "$HOST" "$PORT"; then
log "OK " "${HOST}:${PORT} [${DESC}]"
else
log "FAIL" "${HOST}:${PORT} [${DESC}]"
FAIL_COUNT=$((FAIL_COUNT + 1))
FAIL_LIST="${FAIL_LIST} ${DESC}(${HOST}:${PORT})"
fi
done
if [ "$FAIL_COUNT" -gt 0 ]; then
log "WARN" "점검 완료 — 실패 ${FAIL_COUNT}건:${FAIL_LIST}"
else
log "INFO" "점검 완료 — 전체 정상"
fi
exit "$FAIL_COUNT"
Nagios/Zabbix 등과의 연동
# Nagios 플러그인 형태로 변환
# 종료 코드 규칙: 0=OK, 1=WARNING, 2=CRITICAL, 3=UNKNOWN
if [ "$FAIL_COUNT" -eq 0 ]; then
echo "OK: 전체 ${#TARGETS[@]}개 서버 정상"
exit 0
elif [ "$FAIL_COUNT" -le 1 ]; then
echo "WARNING: ${FAIL_COUNT}개 서버 응답 없음"
exit 1
else
echo "CRITICAL: ${FAIL_COUNT}개 서버 응답 없음"
exit 2
fi
5. 핵심 명령어 요약
| 목적 | 명령어/표현 |
|---|---|
| 타임아웃 포함 포트 점검 | nc -zv -w 3 192.168.1.200 3306 |
| 종료 코드 확인 | echo $? (0=성공, 비0=실패) |
| 타임스탬프 생성 | $(date '+%Y-%m-%d %H:%M:%S') |
| 로그 파일에 기록 | echo "메시지" >> /var/log/netcheck.log |
| bash 배열 선언 | TARGETS=("host1:port1:desc1" "host2:port2:desc2") |
| 배열 순회 | for item in "${TARGETS[@]}"; do ...; done |
| 문자열 파싱 | echo "$item" | cut -d: -f1 |
| cron 5분 주기 | */5 * * * * /opt/scripts/netcheck.sh |
| cron 등록 확인 | crontab -l |
정리
nc -zv -w 3의-w 3은 타임아웃 3초 설정 — 스크립트 무한 대기 방지 필수$?로 nc의 성공/실패 판단 (0=성공, 1=실패)- 배열(
TARGETS=())과for루프로 여러 서버를 간결하게 점검 $(date '+%Y-%m-%d %H:%M:%S')로 타임스탬프를 로그에 함께 기록- crontab
*/5 * * * *으로 5분마다 자동 실행 - cron 실행 전 실행 권한, PATH, 로그 리다이렉션 확인 필수