ホーム 記事一覧

bash で簡単にメールを送信する方法まとめ(sendmail / SMTP AUTH / 添付ファイル)

bash で簡単にメールを送信する方法まとめ

シェルスクリプトからメールを送信したいことは意外とあります。監控スクリプトの通知とか、バッチ処理の結果報告とか。

方法はいくつかありますが、よく使う3つのパターンをまとめます。

  1. sendmail で単純に送信する
  2. SMTP AUTH を設定して送信する
  3. 添付ファイルを付けて送信する

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 で対応可能

スクリプトに組み込む場合は、パスワードをハードコードせず、環境変数や設定ファイルに置くのがおすすめです。