네트워크_11 IP 주소에 따른 처리 분기를 case문으로 작성하기

 
  • 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어

명령어: case, ping
키워드: IP 주소, 분기, 일치, 문자열
사용처: IP 주소마다 다른 처리를 하도록 간단히 분기하고 싶을 때

실행 예제

$ ./ipmatch.sh 192.168.2.1
Ping to 192.168.2.1 : [OK]

$ ./ipmatch.sh 192.168.3.1
192.168.3.1 테스트 대상이 아닙니다.

스크립트

#!/bin/sh

# 대상 IP 주소를 명령행 인수로 지정하지 않으면 에러 표시 후 종료
if [ -z "$1" ]; then # if문 --------------------- 1
    echo "IP 주소를 지정하세요." >&2
    exit 1
fi

# 대상 네트워크라면 ping 명령어 실행
case "$1" in
    192.168.2.*|192.168..10.*) # ---------------- 2
        ping -c 1 "$1" > /dev/null 2>&1 # ------- 3

        if [ $? -eq 0 ]; then # ----------------- 4
            echo "Ping to $1 : [OK]"
        else
            echo "Ping to $1 : [NG]"
        fi
        ;;
        *) # ------------------------------------ 5
            echo "$1 테스트 대상이 아닙니다." >&2
            exit 2
        ;;
esac    

   

해설

이 스크립트는 인수로 지정한 IP 주소에 ping 명령어ICMP 패킷을 보내서 네트워크 개통을 확인합니다. 이때 테스트와 관계없는 네트워크라면 ping 명령어를 실행하지 않도록 처리합니다. 여기에서는 192.168.2.0/24 및 182.168.10.0/24만 테스트 대상이라고 가정합니다.

1에서 test 명령어 -z를 사용해서 명령행 인수가 지정되어 있는지 확인합니다. -z는 빈 문자열일 때 참이 되므로 1의 if문이 참이면 명령행 인수가 없다는 뜻입니다. 따라서 “IP 주소를 지정하세요.”라는 에러를 출력하고 exit 로 에러를 종료합니다.

2에서 입력된 IP 주소를 case 문으로 비교합니다. case문으로 패턴을 비교하는데 * (애스터리스크) 같은 와일드카드를 사용할 수 있습니다. 따라서 192.168.2.0/24라는 네트워크는 192.168.2.*로 비교할 수 있습니다(하지만 이것은 192.168.2.AA 처럼 부정확한 IP 주소도 통과되므로 주의해야 합니다).

3에서 지정한 IP 주소에 ping 명령어를 실행합니다. 실행 횟수를 지정하는 -c 옵션을 사용해서 한 번만 ICMP 패킷을 보냅니다.

3에서 ping 명령어 종료 스테이터스만 필요하고 도중 출력은 필요하지 않으므로 표준 출력과 표준 에러 출력을 /dev/null로 리다이렉트해서 버립니다.

ping 명령어를 실행한 결과, 종료 스테이터스는 셸 특수 변수 $?에 들어 있습니다. 4에서 이 값을 비교합니다. 종료 스테이터스가 0(ping 성공)이면 [OK]를 표시하고 종료 스테이터스가 0 이외(ping 실패) 값이라면 [NG]라고 표시합니다.

case문 분기로 2에서 일치하지 않은 IP주소 즉, 테스트 대상 외 네트워크는 5 분기에서 처리합니다. 5는 case문에 * (애스터리스크)가 있으므로 이전에 일치하지 않은 모든 주소가 해당합니다. 따라서 테스트 대상이 아니라고 표시하고 종료합니다.

이렇게 해서 IP 주소마다 분기해서 테스트하는 처리를 case문으로 작성할 수 있습니다.

   

주의사항

  • 예제에서는 입력한 IP 주소가 정상인지 확인하지 않습니다. AA.AA.AA.AA 같은 문자열도 처리하려고 합니다.