Computer >> Máy Tính >  >> Lập trình >> Lập trình BASH

Cách sử dụng tập lệnh Bash để quản lý tải xuống và xem tệp từ nhóm AWS S3

Như bạn có thể đọc trong bài viết này, gần đây tôi đã gặp một số sự cố với máy chủ email của mình và quyết định thuê ngoài quản trị email cho Dịch vụ Email Đơn giản (SES) của Amazon.

Vấn đề với giải pháp đó là tôi đã để SES lưu các thư mới vào nhóm S3 và việc sử dụng Bảng điều khiển quản lý AWS để đọc các tệp trong nhóm S3 trở nên cũ rất nhanh.

Vì vậy, tôi quyết định viết một tập lệnh Bash để tự động hóa quá trình tải xuống, lưu trữ đúng cách và xem thư mới.

Mặc dù tôi đã viết tập lệnh này để sử dụng trên máy tính để bàn Ubuntu Linux của mình, nhưng nó sẽ không yêu cầu quá nhiều thao tác để làm cho nó hoạt động trên hệ thống macOS hoặc Windows 10 thông qua Hệ thống con Windows dành cho Linux.

Đây là kịch bản hoàn chỉnh tất cả trong một phần. Sau khi bạn dành một chút thời gian để xem qua, tôi sẽ hướng dẫn bạn từng bước một.

#!/bin/bash
# Retrieve new messages from S3 and save to tmpemails/ directory:
aws s3 cp \
   --recursive \
   s3://bucket-name/ \
   /home/david/s3-emails/tmpemails/  \
   --profile myaccount

# Set location variables:
tmp_file_location=/home/david/s3-emails/tmpemails/*
base_location=/home/david/s3-emails/emails/

# Create new directory to store today's messages:
today=$(date +"%m_%d_%Y")
[[ -d ${base_location}/"$today" ]] || mkdir ${base_location}/"$today"

# Give the message files readable names:
for FILE in $tmp_file_location
do
   mv $FILE ${base_location}/${today}/email$(rand)
done

# Open new files in Gedit:
for NEWFILE in ${base_location}/${today}/*
do
   gedit $NEWFILE
done

Chúng tôi sẽ bắt đầu với một lệnh duy nhất để tải xuống bất kỳ thư nào hiện đang nằm trong nhóm S3 của tôi (nhân tiện, tôi đã thay đổi tên của nhóm và các chi tiết xác thực và hệ thống tệp khác để bảo vệ quyền riêng tư của tôi).

aws s3 cp \
   --recursive \
   s3://bucket-name/ \
   /home/david/s3-emails/tmpemails/  \
   --profile myaccount

Tất nhiên, điều này sẽ chỉ hoạt động nếu bạn đã cài đặt và định cấu hình AWS CLI cho hệ thống cục bộ của mình. Bây giờ là lúc để làm điều đó nếu bạn chưa làm.

Các cp lệnh là viết tắt của "copy", --recursive yêu cầu CLI áp dụng thao tác ngay cả với nhiều đối tượng, s3:// bucket-name trỏ tới nhóm của tôi (tên nhóm của bạn rõ ràng sẽ khác), dòng / home / david ... là địa chỉ hệ thống tệp tuyệt đối mà tôi muốn các thư được sao chép và --profile đối số cho CLI biết tôi đang đề cập đến tài khoản AWS nào trong số nhiều tài khoản AWS của tôi.

Phần tiếp theo đặt hai biến sẽ giúp tôi xác định vị trí hệ thống tệp dễ dàng hơn nhiều thông qua phần còn lại của tập lệnh.

tmp_file_location=/home/david/s3-emails/tmpemails/*
base_location=/home/david/s3-emails/emails/

Lưu ý cách giá trị của tmp_file_location biến kết thúc bằng dấu hoa thị. Đó là bởi vì tôi muốn đề cập đến tệp bên trong thư mục đó, thay vì chính thư mục.

Tôi sẽ tạo một thư mục vĩnh viễn mới trong hệ thống phân cấp ... / email / để giúp tôi tìm thư dễ dàng hơn sau này. Tên của thư mục mới này sẽ là ngày hiện tại.

today=$(date +"%m_%d_%Y")
[[ -d ${base_location}/"$today" ]] || mkdir ${base_location}/"$today"

Trước tiên, tôi tạo một biến shell mới có tên là hôm nay sẽ được điền vào đầu ra của ngày + "% m_% d_% Y" yêu cầu. ngày chính nó xuất ra ngày / dấu thời gian đầy đủ, nhưng những gì sau ( "% m_% d_% Y" ) chỉnh sửa xuất ra định dạng đơn giản hơn và dễ đọc hơn.

Sau đó, tôi kiểm tra sự tồn tại của một tên trực tiếp sử dụng tên đó - điều này cho thấy rằng tôi đã nhận được email vào ngày hôm đó và do đó, không cần phải tạo lại thư mục. Nếu một thư mục như vậy không không tồn tại (||), sau đó mkdir sẽ tạo ra nó cho tôi. Nếu bạn không chạy thử nghiệm này, lệnh của bạn có thể trả về các thông báo lỗi khó chịu.

Vì Amazon SES đặt những cái tên xấu xí và khó đọc cho mỗi tin nhắn mà nó đưa vào thùng S3 của tôi, nên bây giờ tôi sẽ tự động đổi tên chúng đồng thời chuyển chúng sang nhà mới (trong thư mục ghi ngày tháng mà tôi vừa tạo) .

for FILE in $tmp_file_location
do
   mv $FILE ${base_location}/${today}/email$(rand)
done

Việc làm ... làm ... xong việc vòng lặp sẽ đọc từng tệp trong thư mục được đại diện bởi $ tmp_file_location và sau đó di chuyển nó vào thư mục tôi vừa tạo (được đại diện bởi $ base_location biến ngoài giá trị hiện tại của $ hôm nay ).

Là một phần của cùng một thao tác, tôi sẽ đặt tên mới cho nó, chuỗi " email "theo sau là một số ngẫu nhiên được tạo bởi rand yêu cầu. Bạn có thể cần cài đặt trình tạo số ngẫu nhiên:đó sẽ là apt install rand trên Ubuntu.

Phiên bản trước đó của tập lệnh đã tạo các tên được phân biệt bằng các số ngắn hơn, liên tiếp được tăng dần bằng cách sử dụng count =1 ... count =$ ((count + 1)) logic trong cho vòng. Điều đó hoạt động tốt miễn là tôi không tình cờ nhận được nhiều hơn một loạt tin nhắn trong cùng một ngày. Nếu tôi làm vậy, thì các tin nhắn mới sẽ ghi đè lên các tệp cũ hơn trong thư mục của ngày hôm đó.

Tôi đoán về mặt toán học có thể là rand của tôi lệnh có thể gán các số trùng lặp cho hai tệp nhưng, với điều kiện là phạm vi mặc định rand sử dụng từ 1 đến 32.576, đó là rủi ro mà tôi sẵn sàng chấp nhận.

Tại thời điểm này, sẽ có các tệp trong thư mục mới với các tên như email3039, email25343, v.v. cho mỗi thư mới mà tôi đã được gửi.

Chạy cây trên hệ thống của riêng tôi cho tôi biết rằng năm thư đã được lưu vào thư mục 02_27_2020 của tôi và một thư nữa vào 02_28_2020 (các tệp này được tạo bằng phiên bản cũ hơn của tập lệnh của tôi, vì vậy chúng được đánh số theo thứ tự).

Hiện không có tệp nào trong tmpemails - đó là bởi vì lệnh mv di chuyển tệp đến vị trí mới của chúng, không để lại gì.

$ tree
.
├── emails
│   ├── 02_27_2020
│   │   ├── email1
│   │   ├── email2
│   │   ├── email3
│   │   ├── email4
│   │   ├── email5
│   └── 02_28_2020
│       └── email1
└── tmpemails

Phần cuối cùng của tập lệnh sẽ mở từng tin nhắn mới trong trình soạn thảo văn bản trên máy tính để bàn yêu thích của tôi (Gedit). Nó sử dụng một for ... do ... done tương tự vòng lặp, lần này đọc tên của từng tệp trong thư mục mới (được tham chiếu bằng cách sử dụng " hôm nay ") và sau đó mở tệp trong Gedit. Lưu ý dấu hoa thị tôi đã thêm vào cuối vị trí thư mục.

for NEWFILE in ${base_location}/${today}/*
do
   gedit $NEWFILE
done

Vẫn còn một việc nữa phải làm. Nếu tôi không dọn sạch bộ chứa S3 của mình, nó sẽ tải xuống tất cả các tin nhắn đã tích lũy mỗi khi tôi chạy tập lệnh. Điều đó sẽ làm cho nó dần dần khó quản lý hơn.

Vì vậy, sau khi tải xuống thành công các tin nhắn mới của mình, tôi chạy tập lệnh ngắn này để xóa tất cả các tệp trong nhóm:

#!/bin/bash
# Delete all existing emails 

aws s3 rm --recursive s3://bucket-name/ --profile myaccount