ディレクトリ内の一致するすべてのファイルを電子メールで送信するスクリプト

ディレクトリ内の一致するすべてのファイルを電子メールで送信するスクリプト

データファイルを自動的に送信するようにbashスクリプトを設定してみてください。必要な最終結果は、週に一度指定されたディレクトリを確認し、過去2日間に変更されたすべてのExcelファイルを一覧表示し、指定された受信者のリストに電子メールを送信することです。

Sendmailを設定して実行しています(Gmailリレーを使用)。設定して動作しています。通常送信するコマンドは、CLIから直接送信すると(添付ファイルを含むメールの送信と受信)機能しますが、スクリプトから呼び出そうとすると繰り返し失敗します。すべては、ディレクトリとファイル名にスペースが含まれているという事実から来ているようです。私はこれを変更することはできません。ファイルの命名を制御できません。しかし、これが私のスクリプトの問題のようです。

2つの主な質問:

  1. すべてのファイルを一度に送信しようとすると、muttは添付ファイルを添付できないことを報告します。
Can't stat "/path\ to/file1.xls
/path\ to/file2.xls": No such file or directory

改行文字は $FILES 変数の一部として渡されます。

  1. 一度に1つのファイルを送信するディレクトリを繰り返すと(一部のファイルがかなり大きいため、目的の結果)、スクリプトはスペースをエスケープするかどうかに関係なく区切り文字として解釈するため、/path/to/the\ files/file\ 1.xls3つの値として扱われます。 (/path/to/the\files/file\1.xls)。

スクリプトの前半は実行されましたが(すべてのファイルを同時に転送)、ループを追加しようとしたときに中断されました。もちろん、以前の実行バージョンは保存されませんでした。正しい区切り文字を得るためにループを試してみましたが、set ifs=$'\n'それを所定の位置に置くと、muttはファイルのフルパスがファイルではないか、指定された受信者がないことを伝えます。本当に怒っています。

スクリプト:

#!/bin/bash
# This file should send an email to specified recipients with data files for the week attached.

# Set reply-to address for Mutt
export REPLYTO="[email protected]"

# Replace with space separated email address of all recipients
EMAILS="[email protected] [email protected]"

# Get today's date for subject
# Date is in YYYY-MM-DD format
TODAY=$(date +%F)

# Set the message body
MBODY="Sending this week's data files.\n"

# Set the starting directory
# Don't bother escaping it, this is fixed in FILES variable below
DIR="/home/user/path to files"

# Get the list of files to send
FILES=$(find "$DIR" -type f -mtime -2 | sed 's/ /\\ /g' | grep ".xls")

# Check to see if we found any files or not
if [ -z "$FILES" ]; then
    MBODY="No matching files added or modified within last 2 days. No files sent.\n"
    echo "$MBODY" | mutt -s "Data files for $TODAY" $EMAILS
fi

# Send all files in a single email
echo $MBODY | mutt -s "Data files for $TODAY" -a "$FILES" -- $EMAILS

ファイルを個別に送信するには、上記の最後の2行の代わりに次のことを試しました。

# Cycle through FILES array and send each file individually
for datafile in ${FILES[*]}
do
   set IFS=$'\n\t'
   echo $MBODY | mutt -s \"Data files for $TODAY\" -a $datafile -- $EMAILS 
   unset $IFS
done

助けが必要ですか?私はこの問題についてしばらく詰まっていました。他の言語で使用する方が簡単な場合は、muttやbashを使用するのが好きではありません。

ベストアンサー1

set "/home/user/path to files/"*.xls
for f do [ "$f" -nt "$two_day_old_file" ] && set "$@" "$f" ; shift ; done
touch "$two_day_old_file"
echo $MBODY | mutt -s "Data files for $TODAY" -a "$@" -- $EMAILS    

一度に1枚ずつ郵送するには、次の行echoを次のように変更してください。

for mailf do echo "$MBODY" | 
    mutt -s "Data files for $TODAY" -a "$mailf" -- $EMAILS
done

うまくいくかもしれませんが、実際の質問は次のとおりです。

...
set IFS=...
...

これは内部フィールド区切り文字の値にはまったく影響を与えず、代わりにその値をIFS=...最初の位置引数またはに割り当てます$1$IFSそれでもあなたの前に来たすべてを大切にしてくださいset $1。あなたがしなければならないことは次のとおりです。

IFS='
   ' 

または...

IFS=${IFS# } 

...デフォルトに設定されている場合は実行可能なスクリプトで、スクリプトで他の項目を変更しない場合は、$IFSデフォルト値を使用する必要があります。$IFS

おすすめ記事