Unix でコマンドの結果である複数のファイルを添付しようとしていますfind
。メールを送信しようとすると、添付ファイルが見つかりません。
dir=$path
echo "Entered into $spr/sum_master"
for fil in `find $dir -ctime -2 -type f -name "Sum*pdf*"`
do
uFiles=`echo "$uFiles ; uuencode $fil $fil"`
done
\($uFiles\) | mailx -s "subject" [email protected]
このコードの何が問題なのでしょうか?
答え1
uFiles
に文字列 が含まれる場合foo bar qux
、最後の行は(foo
引数 および を指定してbar
コマンドを実行しますqux)
。これにより、エラー メッセージ(foo: command not found
(または同様のメッセージ) が表示され、mail
空の入力が取得されます。
スクリプトの問題はそれだけではありません。変数を構築するコマンドは、uFiles
あなたが考えていることをまったく実行しません。bash -x /path/to/script
スクリプトのトレースを確認するために実行してください。何が起こっているかがわかります。コマンドを実行するのではなく、 echo
ing していますuuencode
。次のものは必要ありませんecho
。
uFiles="$uFiles
$(uuencode "$fil" "$fil")"
これでループは機能しますが、脆弱です。特に、スペースやその他の特殊文字を含むファイル名ではループが機能しなくなります(シェル スクリプトが空白文字やその他の特殊文字で動作しなくなるのはなぜですか?を参照してください。 の出力を解析することが、find
何かを実行する最も簡単な方法であることはほとんどありません。代わりに、find
に実行したいコマンドを実行するように指示してください。
find "$dir" -ctime -2 -type f -name "Sum*pdf*" -exec uuencode {} {} \;
その出力は、構築しようとしていた uuencode ファイルの連結です。これをmail
直接入力として渡すことができます:
find "$dir" -ctime -2 -type f -name "Sum*pdf*" -exec uuencode {} {} \; |
mailx -s "subject" [email protected]
uuencode ステップの潜在的な失敗を検出する場合は、それを変数に詰め込むことができます (ただし、非常に大きくなる可能性があることに注意してください)。
attachments=$(find "$dir" -ctime -2 -type f -name "Sum*pdf*" -exec uuencode {} {} \;)
if [ $? -ne 0 ]; then
echo 1>&2 "Error while encoding attachments, aborting."
exit 2
fi
if [ -z "$attachments" ]; then
echo 1>&2 "Notice: no files to attach, so mail not sent."
exit 0
fi
echo "$attachments" | mailx -s "subject" [email protected]
あるいは、一時ファイルを書き込みます。
attachments=
trap 'rm -f "$attachments"' EXIT HUP INT TERM
attachments=$(mktemp)
find "$dir" -ctime -2 -type f -name "Sum*pdf*" -exec uuencode {} {} \; >"$attachments"
if [ $? -ne 0 ]; then
echo 1>&2 "Error while encoding attachments, aborting."
exit 2
fi
if ! [ -s "$attachments" ]; then
echo 1>&2 "Notice: no files to attach, so mail not sent."
exit 0
fi
mailx -s "subject" [email protected] <"$attachments"