bash で簡単にメールを送信する方法まとめ
シェルスクリプトからメールを送信したいことは意外とあります。監控スクリプトの通知とか、バッチ処理の結果報告とか。
方法はいくつかありますが、よく使う3つのパターンをまとめます。
- sendmail で単純に送信する
- SMTP AUTH を設定して送信する
- 添付ファイルを付けて送信する
1. sendmail で単純に送信する
一番シンプルな方法です。サーバーに sendmail がインストールされていれば、これだけでメールが送れます。
前提
sendmail または postfix がインストールされていること。
# sendmail が入っているか確認
which sendmail
送信スクリプト
#!/bin/bash
TO="example@example.com"
SUBJECT="テストメール"
mail -s "$SUBJECT" "$TO" <<EOF
こんにちは。
これは bash スクリプトから送信されたテストメールです。
以上。
EOF
ヒアドキュメントのインデント(<<-)
通常の <<EOF では、終了キーワード EOF も行頭に置かなければなりません。しかし <<-EOF を使うと、タブ文字でインデントされた終了キーワードが許可されます。
#!/bin/bash
TO="example@example.com"
SUBJECT="インデントテスト"
if true; then
mail -s "$SUBJECT" "$TO" <<-EOF
こんにちは。
これはインデントされたヒアドキュメントです。
タブでindentしても問題ありません。
EOF
fi
注意点: <<- はタブ文字のみを除去します。スペースでインデントしている場合は除去されないので、必ずタブを使いましょう。
HTML メールを送る場合
#!/bin/bash
TO="example@example.com"
SUBJECT="HTML メールテスト"
mail -s "$SUBJECT" -a "Content-Type: text/html; charset=UTF-8" "$TO" <<EOF
<h1>テスト</h1>
<p>これは HTML メールです。</p>
EOF
2. SMTP AUTH を設定して送信する
自分のメールサーバー経由で送信したい場合や、Gmail のような SMTP サービスを使う場合は、SMTP AUTH が必要です。
curl を使う方法
curl を使えば、外部 SMTP サーバー経由でメールを送信できます。
#!/bin/bash
SMTP_SERVER="smtp.example.com"
SMTP_PORT="587"
SMTP_USER="your-email@example.com"
SMTP_PASS="your-password"
TO="example@example.com"
SUBJECT="SMTP AUTH テスト"
curl --ssl-reqd \
--url "smtp://${SMTP_SERVER}:${SMTP_PORT}" \
--user "${SMTP_USER}:${SMTP_PASS}" \
--mail-from "${SMTP_USER}" \
--mail-rcpt "${TO}" \
-T <(cat <<EOF
From: ${SMTP_USER}
To: ${TO}
Subject: ${SUBJECT}
SMTP AUTH 経由で送信されたテストメールです。
本文はここに書きます。
EOF
)
Gmail の場合
Gmail の SMTP を使う場合は、アプリパスワードが必要です。
#!/bin/bash
SMTP_SERVER="smtp.gmail.com"
SMTP_PORT="587"
SMTP_USER="your-gmail@gmail.com"
SMTP_PASS="xxxx-xxxx-xxxx-xxxx" # アプリパスワード
TO="example@example.com"
SUBJECT="Gmail SMTP テスト"
curl --ssl-reqd \
--url "smtp://${SMTP_SERVER}:${SMTP_PORT}" \
--user "${SMTP_USER}:${SMTP_PASS}" \
--mail-from "${SMTP_USER}" \
--mail-rcpt "${TO}" \
-T <(cat <<EOF
From: ${SMTP_USER}
To: ${TO}
Subject: ${SUBJECT}
Gmail 経由で送信されたテストメールです。
本文はここに書きます。
EOF
)
SSL/TLS のポート番号
- 587: STARTTLS(通常はこれを使う)
- 465: SSL/TLS(暗号化された接続)
3. 添付ファイルを付けて送信する
curl で添付ファイルを送る
#!/bin/bash
SMTP_SERVER="smtp.example.com"
SMTP_PORT="587"
SMTP_USER="your-email@example.com"
SMTP_PASS="your-password"
TO="example@example.com"
SUBJECT="添付ファイル付きメール"
ATTACHMENT="/var/log/backup.log"
curl --ssl-reqd \
--url "smtp://${SMTP_SERVER}:${SMTP_PORT}" \
--user "${SMTP_USER}:${SMTP_PASS}" \
--mail-from "${SMTP_USER}" \
--mail-rcpt "${TO}" \
-F "=(;type=multipart/mixed" \
-F "From=${SMTP_USER}" \
-F "To=${TO}" \
-F "Subject=${SUBJECT}" \
-F "$(cat <<EOF
ログファイルを添付します。
EOF
);type=text/plain;charset=UTF-8" \
-F "file=@${ATTACHMENT}" \
-F "=)"
複数の添付ファイルを送る
#!/bin/bash
SMTP_SERVER="smtp.example.com"
SMTP_PORT="587"
SMTP_USER="your-email@example.com"
SMTP_PASS="your-password"
TO="example@example.com"
SUBJECT="複数ファイル添付"
FILES=("/var/log/app1.log" "/var/log/app2.log" "/var/log/app3.log")
# ファイルリストを作成
FILE_ARGS=""
for f in "${FILES[@]}"; do
FILE_ARGS="$FILE_ARGS -F \"file=@${f}\""
done
eval curl --ssl-reqd \
--url "smtp://${SMTP_SERVER}:${SMTP_PORT}" \
--user "${SMTP_USER}:${SMTP_PASS}" \
--mail-from "${SMTP_USER}" \
--mail-rcpt "${TO}" \
-F "=(;type=multipart/mixed" \
-F "From=${SMTP_USER}" \
-F "To=${TO}" \
-F "Subject=${SUBJECT}" \
-F "$(cat <<EOF
複数のログファイルを添付します。
EOF
);type=text/plain;charset=UTF-8" \
$FILE_ARGS \
-F "=)"
実用的な例:バックアップ結果を通知する
実際の運用で使いやすいサンプルです。
#!/bin/bash
# 設定
SMTP_SERVER="smtp.example.com"
SMTP_PORT="587"
SMTP_USER="your-email@example.com"
SMTP_PASS="your-password"
TO="admin@example.com"
BACKUP_DIR="/backup"
LOG_FILE="/var/log/backup.log"
DATE=$(date +%Y%m%d)
# バックアップ実行
echo "[$DATE] バックアップ開始" >> "$LOG_FILE"
tar czf "${BACKUP_DIR}/backup-${DATE}.tar.gz" /var/www/ 2>> "$LOG_FILE"
RESULT=$?
# 結果に応じて件名と本文を変える
if [ $RESULT -eq 0 ]; then
SUBJECT="[成功] バックアップ結果 ${DATE}"
ATTACHMENT="${BACKUP_DIR}/backup-${DATE}.tar.gz"
BODY=$(cat <<-EOF
バックアップが正常に完了しました。
対象: /var/www/
ファイル: backup-${DATE}.tar.gz
EOF
)
else
SUBJECT="[失敗] バックアップ結果 ${DATE}"
ATTACHMENT="$LOG_FILE"
BODY=$(cat <<-EOF
バックアップに失敗しました。
ログを確認してください。
EOF
)
fi
# メール送信
curl --ssl-reqd \
--url "smtp://${SMTP_SERVER}:${SMTP_PORT}" \
--user "${SMTP_USER}:${SMTP_PASS}" \
--mail-from "${SMTP_USER}" \
--mail-rcpt "${TO}" \
-F "=(;type=multipart/mixed" \
-F "From=${SMTP_USER}" \
-F "To=${TO}" \
-F "Subject=${SUBJECT}" \
-F "${BODY};type=text/plain;charset=UTF-8" \
-F "file=@${ATTACHMENT}" \
-F "=)"
echo "[$DATE] メール送信完了" >> "$LOG_FILE"
まとめ
| 方法 | 用途 | 必要なもの |
|---|---|---|
mail コマンド |
単純な通知 | sendmail / postfix |
curl + SMTP AUTH |
外部SMTP利用 | curl |
curl + 添付ファイル |
ログ送信など | curl |
- 単純な通知なら
mailコマンドが一番早い - Gmail や外部 SMTP を使う場合は
curlが便利 - 添付ファイルも
curlで対応可能
スクリプトに組み込む場合は、パスワードをハードコードせず、環境変数や設定ファイルに置くのがおすすめです。