1. 사용 명령어 |
(1) host
(2) awk
(3) sed
2. 키워드 & 사용처 |
(1) 키워드
IP 주소, 호스트명, 변환, DNS
(2) 사용처
IP 주소가 적힌 파일을 읽어서 호스트명을 함께 표시하고 싶을 때 사용합니다.
3. 실행 예제 |
$ cat ip.txt <- IP 주소가 적힌 파일
198.51.100.43
203.0.113.1
203.0.113.198
$ ./revlookup.sh ip.txt
198.51.100.43,www.example.org
203.0.113.1,mail.example.com
203.0.113.198,
4. 스크립트 |
#!/bin/sh
while read ipaddr ①
do
# host 명령어로 IP 주소 변환
revlookup=$(host "$ipaddr") ②
# host 명령어가 성공했는지
if [ $? -eq 0]; then ③
ehco -n "$ipaddr," ④
# host 명령어 출력을 awk로 호스트명만 표시
echo "$revlookup" | awk '{print $NF}' | sed 's/\.$//' ⑤
else
echo"$ipaddr,"
fi
# DNS서버 부하 경함을 위해 1초간 대기
sleep 1 ⑥
done < $1
5. 해설 |
이 스크립트는 IP 주소가 적힌 파일(ip.txt)을 읽어서 각각의 IP 주소를 host 명령어로 호스트명으로 변환해서 'IP 주소, 호스트명' 조합의 CSV 파일로 출력합니다.
아파치를 비롯한 서버 소프트웨어 로그 파일에는 접속한 IP 주소가 기록됩니다. 이런 로그를 분석할 때 IP 주소를 호스트명으로 바꾸면 상대방의 ISP나 회선을 알기 쉬우므로 이런 변환을 자주하게 됩니다.
IP 주소 변환은 다음처럼 IP 주소를 DNS 서버에 문의해서 호스트명을 취득합니다.
DNS로 이름 해석을 할 때는 호스트명에서 IP 주소를 얻습니다. 이 경우는 반대로 IP 주소에서 호스트명을 얻으므로 변환이라고 합니다.
예제 ①에서 while문으로 read 명령어를 실행해서 파일에서 IP 주소를 읽어 셸 변수 ipaddr에 저장합니다. 이 파일은 다음처럼 IP 주소가 나열되어 있다고 가정합니다.
198.51.100.43
203.0.113.1
203.0.113.198
한편 while문 마지막 줄(done) 뒤에서 명령행 인수 $1을 입력 리다이렉트합니다. 따라서 read 명령어를 사용해 파일 내용을 한 줄씩 셸 변수 ipaddr로 읽어들이게 됩니다.
②에서 IP 주소에서 호스트명을 변환하기 위해 host 명령어를 실행해서 그 결과를 명령어 치환 $()으로 셸 변수 revlookup에 대입합니다.
③에서 host 명령어 종료 스테이터스를 특수 변수 $?로 판별합니다. host 명령어가 정상적으로 변환했으면 종료 스테이터스인 $?는 0(정상 종료)이 됩니다. 만약 실패했다면 종료 스테이터슨느 0이 아닌 값이 되므로 if 문으로 성공했는지 실패했는지에 따라 분기합니다.
정상적으로 변환했으면 [IP주소,호스트명]을 출력하기 위해 ④에서 echo 명령어를 줄바꿈 없는 -n 옵션으로 실행해서 IP 주소를 표시합니다. echo 명령어의 -n 옵션은 Mac에서 에러가 발생하므로 주의해야 합니다.
⑤에서는 호스트명을 표시합니다. 변환된 호스트명은 host 명령어 표시 결과 마지막에 있으므로 awk 명령어를 사용해서 마지막 컬럼 $NF를 출력합니다. NF란 awk 명령어에서 '마지막 컬럼'을 의미하는 변수입니다.
$ host 198.51.100.43
43.100.51.198.in-addr.arpa domain name pointer ww.example.org.
host 명령어 출력을 보면 호스트명 뒤에 .이 붙어있습니다. 따라서 ⑤에서 awk 명령어를 파이프로 이어서 sed 명령어에 넘겨 sed 명령어로 줄 끝에 있는 .을 삭제합니다. 줄 끝에 있는 점을 \.$라는 패턴으로 일치시켜 이걸 빈 문자열로 치환하면 삭제할 수 있습니다.
⑥에서 1초간 기다립니다. DNS 서버에 부하가 걸리지 않도록 하는 처리입니다. host 명령어는 외부 DNS 서버에 문의하는 명령어이므로 이 예제처럼 IP주소를 파일에서 읽어서 순서대로 처리할 때 파일 크기가 크면 대량의 DNS 문의가 발생하게 됩니다. 이런 행동은 서버에 부하가 걸리므로 여기에서는 1초씩 기다려서 DNS 서버 부하를 제어합니다.
<주의사항>
예제에서 사용하는 IP 주소는 RFC 6890에 정의된 것으로 실제 IP주소가 아닙니다. 예제를 실행할 때는 존재하는 IP 주소로 바꿔서 수행하시기 바랍니다.
참고서적 : 유닉스 리눅스 셸 스크립트 예제 사전
'IT 이야기 > Linux 셸 스크립트' 카테고리의 다른 글
[Linux 셸 스크립트] 네트워크 - 062 간이 TCP 서버 띄우기 (0) | 2021.04.06 |
---|---|
[Linux 셸 스크립트] 네트워크 - 061 서버의 특정 포트가 열려 있는지 확인하는 스크립트 작성하기 (0) | 2021.04.06 |
[Linux 셸 스크립트] 네트워크 - 059 호스트명으로 IP 주소 취득하기 (0) | 2021.03.31 |
[Linux 셸 스크립트] 네트워크 - 058 arp 테이블에서 지정 IP 주소에 대응하는 MAC 주소를 표시하기 (0) | 2021.03.31 |
[Linux 셸 스크립트] 네트워크 - 057 ping으로 특정 호스트 응답 평균 시간을 취득하기 (0) | 2021.03.30 |
댓글