Isso é por causa da divisão de palavras . Se SUBJECT contiver some random theme , então mail -s $SUBJECT será igual a mail -s some random theme . O conteúdo de $subject é dividido em palavras no espaço em branco. Você precisa usar aspas: mail -s "$SUBJECT" .
Sobre os anexos, você provavelmente precisará adicionar a opção -A para cada arquivo. Assim, em vez de -A file1 file2 , talvez seja necessário -A file1 -A file2 . Se os nomes dos seus arquivos não contiverem espaço em branco, você poderá adicionar o -A em ATTACHMENTS para cada nome de arquivo, por exemplo: ATTACHMENTS="$ATTACHMENTS -A $attachment" e usar $ATTACHMENTS no comando mail (você não usa) Não quero aspas aqui, uma vez que os nomes das opções e dos arquivos precisam ser divididos).
A maneira correta seria, claro, usar uma matriz para manter os argumentos da linha de comando, mas o seu for loop já causa a divisão de palavras nos anexos, portanto, uma matriz não ajudaria.
Então:
for f in files... ; do
ATTACHMENTS="-A $f"
done
echo "$BODY" | mail -r "$FROM" -s "$SUBJECT" $ATTACHMENTS "$TO"
Também presumo que você tenha verificado seu mail usa -A para receber anexos. Existem várias versões de mail e as que encontrei não conhecem essa opção. Por exemplo. aquele cujo página de manual está no die.net leva -a para anexos, e usa -A para algo outro. Então, você pode querer checar se isso não funciona.