이전 글에서 언급했듯이, 최근 메일 서버에 문제가 생기면서 이메일 관리 업무를 아마존의 Simple Email Service(SES)로 위임하기로 결정했습니다.
그런데 이 방식에는 한 가지 문제가 있었습니다. SES가 새 메시지를 S3 버킷에 저장하도록 설정했는데, AWS Management Console을 통해 S3 버킷 안의 파일을 일일이 확인하는 작업은 금방 지겨워진다는 점입니다.
그래서 새 메시지를 자동으로 다운로드하고, 체계적으로 보관하고, 바로 열어볼 수 있도록 Bash 스크립트를 작성하게 되었습니다.
이 스크립트는 제 우분투(Ubuntu) 리눅스 데스크톱 환경에서 사용하도록 작성했지만, macOS나 Windows 10의 WSL(Windows Subsystem for Linux) 환경에서도 큰 수정 없이 동작하도록 만들 수 있습니다.
전체 스크립트
먼저 완성된 스크립트 전문을 소개합니다. 잠시 훑어본 후, 단계별로 하나씩 자세히 설명해 드리겠습니다.
#!/bin/bash
# S3에서 새 메시지를 가져와 tmpemails/ 디렉터리에 저장:
aws s3 cp \
--recursive \
s3://bucket-name/ \
/home/david/s3-emails/tmpemails/ \
--profile myaccount
# 위치 변수 설정:
tmp_file_location=/home/david/s3-emails/tmpemails/*
base_location=/home/david/s3-emails/emails/
# 오늘 날짜의 메시지를 저장할 새 디렉터리 생성:
today=$(date +"%m_%d_%Y")
[[ -d ${base_location}/"$today" ]] || mkdir ${base_location}/"$today"
# 메시지 파일에 읽기 쉬운 이름 부여:
for FILE in $tmp_file_location
do
mv $FILE ${base_location}/${today}/email$(rand)
done
# 새 파일을 Gedit으로 열기:
for NEWFILE in ${base_location}/${today}/*
do
gedit $NEWFILE
done1단계: S3 버킷에서 메시지 다운로드
스크립트는 S3 버킷에 쌓여 있는 메시지를 내려받는 단 한 줄의 명령으로 시작합니다. (참고로 개인정보 보호를 위해 버킷 이름과 파일 시스템 경로, 인증 정보 등은 모두 변경했습니다.)
aws s3 cp \
--recursive \
s3://bucket-name/ \
/home/david/s3-emails/tmpemails/ \
--profile myaccount물론 이 명령은 로컬 시스템에 AWS CLI가 이미 설치·설정되어 있어야 동작합니다. 아직이라면 지금 바로 설치하고 구성해 두는 것이 좋습니다.
각 옵션의 의미는 다음과 같습니다. cp는 '복사(copy)'를 뜻하고, --recursive는 여러 객체에도 연산을 적용하라는 의미입니다. s3://bucket-name은 대상 버킷을 가리키며(실제 사용 시에는 본인의 버킷 이름을 넣으면 됩니다), 그다음 줄은 메시지를 복사할 절대 경로입니다. 마지막으로 --profile 인수는 여러 AWS 계정 중 어떤 계정을 사용할지 CLI에 알려줍니다.
2단계: 위치 변수 설정
다음 섹션에서는 스크립트 전반에서 파일 시스템 경로를 손쉽게 지정할 수 있도록 두 개의 변수를 정의합니다.
tmp_file_location=/home/david/s3-emails/tmpemails/*
base_location=/home/david/s3-emails/emails/tmp_file_location 변수 값이 별표(*)로 끝나는 점에 주목하세요. 디렉터리 자체가 아니라 그 안에 있는 파일들을 참조하기 위함입니다.
3단계: 날짜별 저장 디렉터리 생성
나중에 메시지를 쉽게 찾을 수 있도록 .../emails/ 하위에 새 영구 디렉터리를 만듭니다. 디렉터리 이름은 현재 날짜로 지정합니다.
today=$(date +"%m_%d_%Y")
[[ -d ${base_location}/"$today" ]] || mkdir ${base_location}/"$today"먼저 date +"%m_%d_%Y" 명령의 출력값으로 채워지는 today라는 셸 변수를 생성합니다. date 명령은 원래 전체 날짜·시간 정보를 출력하지만, 뒤에 붙인 포맷 문자열("%m_%d_%Y")이 이를 더 간결하고 읽기 쉬운 형태로 바꿔 줍니다.
그다음 해당 이름의 디렉터리가 이미 존재하는지 검사합니다. 디렉터리가 있다면 그날 이미 메일을 받았다는 뜻이므로 다시 만들 필요가 없습니다. 디렉터리가 존재하지 않을 경우(||)에만 mkdir이 새로 생성합니다. 이 검사를 생략하면 매번 성가신 오류 메시지가 출력될 수 있습니다.
4단계: 파일 이름 변경 및 이동
Amazon SES는 S3 버킷에 저장되는 각 메시지에 알아보기 어려운 이름을 붙입니다. 그래서 파일들을 방금 만든 날짜 디렉터리로 옮기면서 동시에 새 이름을 동적으로 부여합니다.
for FILE in $tmp_file_location
do
mv $FILE ${base_location}/${today}/email$(rand)
donefor...do...done 루프는 $tmp_file_location 변수가 가리키는 디렉터리의 각 파일을 하나씩 읽어, 방금 생성한 디렉터리($base_location 변수와 $today 값의 조합)로 이동시킵니다.
같은 과정에서 "email" 문자열 뒤에 rand 명령이 생성한 난수를 붙여 새 이름을 지정합니다. 난수 생성기가 설치되어 있지 않다면 우분투 기준 apt install rand로 설치할 수 있습니다.
초기 버전의 스크립트는 count=1...count=$((count+1)) 로직으로 증가하는 짧은 순차 번호를 사용했습니다. 같은 날 메일을 한 번만 받는다면 문제없이 동작했지만, 하루에 여러 번 실행하면 새 메시지가 기존 파일을 덮어써 버리는 문제가 있었습니다.
이론상 rand 명령이 두 파일에 같은 숫자를 부여할 가능성도 있지만, 기본 범위가 1부터 32,576 사이이므로 감수할 만한 위험이라고 판단했습니다.
5단계: 결과 확인
여기까지 진행하면 새 디렉터리에는 email3039, email25343처럼 이름이 바뀐 메시지 파일들이 담겨 있어야 합니다.
실제로 제 시스템에서 tree 명령을 실행해 보면 02_27_2020 디렉터리에 다섯 통, 02_28_2020에 한 통의 메시지가 저장된 것을 확인할 수 있습니다(이 파일들은 구버전 스크립트로 생성된 것이라 순차 번호가 붙어 있습니다).
tmpemails 디렉터리가 비어 있는 이유는 mv 명령이 파일을 새 위치로 '이동'시키기 때문입니다. 원래 자리에는 아무것도 남지 않습니다.
$ tree
.
├── emails
│ ├── 02_27_2020
│ │ ├── email1
│ │ ├── email2
│ │ ├── email3
│ │ ├── email4
│ │ ├── email5
│ └── 02_28_2020
│ └── email1
└── tmpemails6단계: Gedit으로 새 메시지 열기
스크립트의 마지막 부분은 새 메시지를 제가 즐겨 쓰는 데스크톱 텍스트 편집기인 Gedit으로 여는 작업입니다. 앞서와 비슷한 for...do...done 루프를 사용하며, 이번에는 새 디렉터리("today") 안의 각 파일 이름을 읽어 Gedit으로 엽니다. 디렉터리 경로 끝에 붙은 별표(*)에 유의하세요.
for NEWFILE in ${base_location}/${today}/*
do
gedit $NEWFILE
done마무리: S3 버킷 정리
아직 할 일이 하나 더 남아 있습니다. S3 버킷을 비우지 않으면 스크립트를 실행할 때마다 누적된 모든 메시지를 다시 내려받게 되고, 시간이 지날수록 관리가 점점 어려워집니다.
따라서 새 메시지를 성공적으로 내려받은 후에는 아래 짧은 스크립트로 버킷의 모든 파일을 삭제합니다.
#!/bin/bash
# 기존 이메일 모두 삭제
aws s3 rm --recursive s3://bucket-name/ --profile myaccount이렇게 하면 S3에 도착하는 새 이메일을 로컬에서 날짜별로 깔끔하게 정리하고, 원클릭에 가까운 방식으로 바로 열어볼 수 있는 자동화 파이프라인이 완성됩니다.