서버관리_16 웹 페이지 변경 감시하기

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

명령어: curl, cmp, echo, date
키워드: URL, 파일 변경, 감시
사용처: 비정기적으로 변경되는 웹 사이트 내용을 감시해서 변경이 있으면 알리고 싶을 때

실행 예제

$ ./url-diffcheck.sh
[2023/09/09 15:15:15] 파일이 변경되었습니다.
대상 URL: http://www.example.org/update.html

스크립트

#!/bin/sh

# 감시 대상 URL
url="http://www.example.org/update.html" # ----- 1

# 내려받기 파일명 정의
newfile="new.dat" # ---------------------------- 2
oldfile="old.dat"

# 파일 내려받기
curl -so "$newfile" "$url" # ------------------- 3

# 이전에 내려받은 파일과 "3" 에서 내려 받은 파일 비교
cmp -s "$newfile" "$oldfile" # ----------------- 4

# cmp 명령어 종료 스테이터스가 0이 아니면 차이가 존재
if [ $? -ne 0 ]; then # ------------------------ 5
  # 현재 시각을 [2023/09/08 15:15:15] 형태로 조합
  date_str=$(date +'%Y/%m/%d %H:%M:%S') # ------ 6

  # 파일 변경 알림
  echo "[$date_str] 파일이 변경되었습니다." # -------- 7
  echo "대상 URL: $url"
  /home/user1/bin/alert.sh
fi

# "3"에서 내려 받은 파일을 파일명을 변경해서 저장
mv -f "$newfile" "$oldfile" # ------------------ 8

해설

이 스크립트는 지정한 URL에서 파일을 내려받아서 그 파일이 이전 스크립트 실행 시 내려받은 파일과 다르면 알림을 출력합니다. 그때 alert.sh라는 스크립트를 실행합니다. 이 alert.sh는 알림 메일을 보내거나 하는 어떤 경고를 출력하는 스크립트라고 가정합니다.

어떤 URL로 수치 데이터가 공개되어서 그것이 비정기적으로 갱신된다고 할 때 정기적으로 파일을 내려받아서 이전에 받았던 파일과 차이가 있는지 자동으로 확인할 수 있으면 편리하겠지요. 예제에서는 그런 특정 URL 변경 감시를 다룹니다. 하루에 한 번 정기적으로 실행하면 되겠습니다.

1에서 대상 URL을 지정해서 셸 변수 url에 대입합니다. 스크립트는 바이너리 파일도 변경 비교를 할 수 있는 cmp 명령어를 사용합니다. 따라서 지정한 URL에는 HTML 파일 등 텍스트 기반의 파일뿐만 아니라 JPG 파일 같은 바이너리 파일을 지정해도 됩니다.

2에서 내려받은 파일을 저장할 때 파일명을 지정합니다. 스크립트 실행 시 저장할 파일명을 셸 변수 newfile로, 이전 실행 때 저장한 파일명을 셸 변수oldfile로 정의합니다.

3에서 curl 명령어를 사용해서 대상 URL에서 파일을 내려받습니다. curl 명령어는 아무것도 표시하지 않는 -s(silent) 옵션과 출력 파일명을 지정하는 -o 옵션을 이용합니다. 이걸로 셸 변수 url로 지정한 URL에서 셸 변수 newfile로 지정한 파일명으로 저장합니다.

4는 방금 내려받은 파일과 이전에 내려받은 파일을 cmp 명령어로 비교합니다. cmp 명령어는 두 파일 내용을 비교합니다. 두 텍스트 파일 차이를 보는 diff 명령어와 달리 파일을 1바이트씩 비교하기 때문에 바이너리 파일도 비교할 수 있습니다.

cmp 명령어는 종료 스테이터스에 따라 다음과 같은 의미가 있습니다.

  • cmp 명령어 종료 스테이터스

    종료 스테이터스 의미
    0 두 파일이 같음
    1 두 파일이 다름
    2 저정한 파일을 찾지 못하는 등 에러 발생

4에서 cmp 명령어 종료 스테이터스만 사용하므로 아무것도 출력하지 않는 -s 옵션을 지정합니다.

5는 cmp 명령어 종료 스테이터스 $?를 이용해서 if문으로 분기합니다. 여기서 종료 스테이터스가 0이 아니면 차이가 있다고 보고 if문 안의 명령어를 실행합니다.

6에서 date 명령어를 사용해서 현재 시각을 2023/09/08 15:15:15처럼 조합합니다. 현재 시각을 7에서 파일 변경이 있었다는 알림을 표시합니다. alert.sh는 메일을 보내는 등 상황에 맞게 수정해서 사용하기 바랍니다.

마지막으로 8에서는 이번에 내려받은 파일을 저장하기 위해 mv 명령어로 파일명을 바꿉니다. 이전에 내려받은 파일을 덮어쓰므로 덮어쓰기 확인을 하지 않도록 -f 옵션을 사용합니다.

이렇게 해서 URL로 지정한 파일 변경 감시를 할 수 있습니다. cron에 등록해서 하루에 한 번식 정기적으로 실행하면 되겠습니다.

주의사항

  • 만약 대상 파일 크기가 커서 디스크 용량이 걱정된다면 파일 해시값만 저장하는 방법도 있습니다. MD5값만 저장해서 이전 값과 비교하는 방법입니다. 해시값을 비교하면 파일이 변경되었는지 알 수 있으므로 파일 자체를 저장할 필요 없이 디스크 용량도 절약할 수 있습니다.

  • 최초로 이 스크립트를 실행하면 이전에 내려받은 파일이 없어서 cmp 명령어에 실패하므로 변경되었다고 표시하게 됩니다.

  • FreeBSD는 curl이 기본 설치되지 않으므로 대신에 fetch 명령어를 이용합니다.

    fetcho -qo "$newfile" "$url"