简体   繁体   中英

BASH: Send HTML email with a list of files in boby

Trying to use the "find" command to list of files and send as a list instead of a one line list.

expecting outcome on body of the email listing the files (see bodyHTML line as well):

file1
file2
file3

current outcome:

"file1,file2,file3" <--not want I want on the body of the email.
FOLDER="/temp"
FILES="$(sudo find $FOLDER/*.txt -cmin -60 -type f)"
FILES_COUNT=$($FILES | wc -l)


    EMAIL_TO="###"
    FROM_EMAIL="###"
    FROM_NAME="TEST"
    SUBJECT="TEST"
    TODATE=$(date "+ %D %T")
    
    bodyHTML="<div><H2 style='color:grey;'>$FILES_COUNT Total new files on $TODATE</H2><Table border=1 cellpadding=5 cellspacing=0><TR bgcolor=white align=left><TD><B>$FILES</B></TD></TR>"

    maildata='{"personalizations": [{"to": [{"email": "'${EMAIL_TO}'"}]}],"from": {"email": "'${FROM_EMAIL}'", 
        "name": "'${FROM_NAME}'"},"subject": "'${SUBJECT}'","content": [{"type": "text/html", "value": "'$bodyHTML'"}]}'

    curl --request POST \
    --url https://api.sendgrid.com/v3/mail/send \
    --header 'Authorization: Bearer '$SENDGRID_API_KEY \
    --header 'Content-Type: application/json' \
    --data "'$maildata'"

When I use:

FILES="$(sudo find $FOLDER/*.txt -cmin -60 -type f)"

echo $FILES

outcome: 
/temp/test.txt /temp/tes2.txt /temp/test3.txt /temp/test4.txt /temp/test5.txt

When I don't use echo before $FILES:

$FILES
outcome: 
Endless loop of the follow below:

"/temp/test1.txt: line 88: +oAtMghU1YTaI+6doyj1Z7cALL5ATHPmrxLQweNYFv2S7WuIryTq9k+LaiQnDo9/: No such file or directory"

I honestly don't unterstand your result. But if you want to put the list auf found files into the variable FILES you have to execute the find and assign it's output like you allready do with the FILES_COUNT . And not assign the command as string.

So changing this:

FILES="sudo find $FOLDER/*.txt -cmin -60 -type f"

to this

FILES=$(sudo find $FOLDER/*.txt -cmin -60 -type f)

might do the trick.

At least this simplified example returns the desired output:

ls -1
file1
file2
file3
FILES=$(find * -type f)
echo $FILES
file1 file2 file3

Did you edit?
FILES="sudo find $FOLDER/*.txt -cmin -60 -type f" is just a string...
Did you mean FILES=$(sudo find $FOLDER/*.txt -cmin -60 -type f) ?

The simple answer is that your problem is here: <B>${FILES[*]}</B>
You are sending the list of files in HTML, which cares not one bit about the embedded newlines. Your <B>...</B> tags appear only once, at the beginning and end of the list.

Assuming your filenames are perfect and pristine with no embedded spaces or anything that will cause this logic to crash and burn, then for a quick and dirty solution, try this -

sed -E 's/^(.*)$/<b>\1<\/b>/g' <<< "$FILES"

You should probably just be assigning with

# DEFINITELY keep the quotes *around* the subshell...
FILES="$(sudo find /temp/*.txt -cmin -60 -type f | sed -E 's/^(.*)$/<b>\1<\/b>/g')"

then instead of <B>${FILES[*]}</B> , just use $FILES .

You aren't using an array, btw. ${FILES[*]} isn't buying you anything here.
FILES is just one big string with all the filenames in it, terminated individually by newlines as returned from the find .

$: x="1
> 2
> 3"
$: echo $x # unquoted strips the formatting (the embedded newlines)
1 2 3
$: echo "$x"
1
2
3
$: echo "${x[*]}" # this is almost never what you want
1
2
3
$: echo "[${x[0]}] [${x[1]}] [${x[2]}]"
[1
2
3] [] []
$: echo "[${x:2:2}]" # if you want substrings, use this (var:start:length)
[2
]

# what we did above:
$: sed -E 's/^(.*)$/<b>\1<\/b>/g' <<< "$x"
<b>1</b>
<b>2</b>
<b>3</b>

Do look carefully at the sections on find in https://mywiki.wooledge.org/ParsingLs though. I'd probably make the list with a glob and then carefully check the properly quoted filenames with stat , personally.

Good luck.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM