- 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어
명령어: 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"