Send multiple files by email and also add a body message to the email (Unix Korn Shell) - shell

I'm trying to send multiple files by email but also include a body message in the email, I've tried couple of ways with no luck, the following code is for send multiple files:
(uuencode file1.txt file1.txt ; uuencode file2.txt file2.txt) | mailx -s "test" email#test.com
I've tried this option with no luck:
echo "This is the body message" | (uuencode file1.txt file1.txt ; uuencode file2.txt file2.txt) | mailx -s "test" email#test.com
any idea how could be the code?

Try this:
(echo "This is the body message"; uuencode file1.txt file1.txt; uuencode file2.txt file2.txt) | mailx -s "test" email#test.com
The issue with your command is that you are piping the output of echo into the subshell and it is getting ignored as uuencode isn't reading from stdin.
You can use { ... } to avoid the subshell:
{ echo "This is the body message"; uuencode file1.txt file1.txt; uuencode file2.txt file2.txt; } | mailx -s "test" email#test.com
If you are doing this in a script and you want it to look more readable, then:
{
echo "This is the body message"
uuencode file1.txt file1.txt
uuencode file2.txt file2.txt
} | mailx -s "test" email#test.com

Related

How to insert name field in mailx

My sample data File is
$ cat /fullpath/myfile.csv
a#gmail.com, A Singh
k#gmail.com, K Singh
I am using script.sh
#!/bin/bash
while IFS= read -r line
do
email=$(echo $line | awk -F, '{print $1 }')
name=$(echo $line | awk -F, '{print $2 }')
echo | mailx -v -s "Helo $name" -S smtp-use-starttls -S ssl-verify=ignore -S smtp-auth=login -S smtp=smtp://smtp.gmail.com:587 -S from="xxxx#gmail.com(John Smith)" -S smtp-auth-user=xxxx#gmail.com -S smtp-auth-password=xxxxpassword -S ssl-verify=ignore -S nss-config-dir=~/.certs "$name<$email>"
done < /fullpath/myfile.csv
what is the correct syntax of adding receiver name
I am looking for syntax which I am not able to find
I tried below
"$name<$email>"
$name<$email>
-S to:"$name<$email>"
-S To:"$name<$email>"
-S To: "$name <$email>"
-S To: $name <$email>
its picking names (A Singh) as email and say invalid email. if i use To, it pick TO as email. i.e. whatever come 1st after certs code pic that as email.
According to the standard documentation, mailx does not seem to support the -S option, but some systems may add this option.
I recommend you use GNU Mailutils.
To specify a "FROM" name and address, you can use the "-a" option.
-a header:value
--append=header:value
Append the given header to the composed message.
To specify the receiver name and address, just like you did, add name and email to the end of the command will do the work.
#!/bin/bash
while IFS= read -r line
do
email=$(echo $line | awk -F, '{print $1 }')
name=$(echo $line | awk -F, '{print $2 }')
mail -s "Hello $name" -a "From: John Smith<xxxx#gmail.com>" "$name<$email>"
#echo | mailx -v -s "Helo $name" -S smtp-use-starttls -S ssl-verify=ignore -S smtp-auth=login -S smtp=smtp://smtp.gmail.com:587 -S from="xxxx#gmail.com(John Smith)" -S smtp-auth-user=xxxx#gmail.com -S smtp-auth-password=xxxxpassword## -S ssl-verify=ignore -S nss-config-dir=~/.certs "$name<$email>"
done < ./myfile.csv

How do I check the HTTP status code and also parse the payload

Imagine I have the following code in a bash script:
curl -s https://cat-fact.herokuapp.com/facts/random?animal=cat | jq .
Notice that I wish to display the payload of the response by passing it to jq.
Now suppose sometimes those curls sometimes return a 404, in such cases my script currently still succeeds so what I need to do is check the return code and exit 1 as appropriate (e.g. for a 404 or 503). I've googled around and found https://superuser.com/a/442395/722402 which suggests --write-out "%{http_code}" might be useful however that simply prints the http_code after printing the payload:
curl -s --write-out "%{http_code}" https://cat-fact.herokuapp.com/facts/random?animal=cat | jq .
$ curl -s --write-out "%{http_code}" https://cat-fact.herokuapp.com/facts/random?animal=cat | jq .
{
"_id": "591f98783b90f7150a19c1ab",
"__v": 0,
"text": "Cats and kittens should be acquired in pairs whenever possible as cat families interact best in pairs.",
"updatedAt": "2018-12-05T05:56:30.384Z",
"createdAt": "2018-01-04T01:10:54.673Z",
"deleted": false,
"type": "cat",
"source": "api",
"used": false
}
200
What I actually want to is still output the payload, but still be able to check the http status code and fail accordingly. I'm a bash noob so am having trouble figuring this out. Help please?
I'm using a Mac by the way, not sure if that matters or not (I'm vaguely aware that some commands work differently on Mac)
Update, I've pieced this together which sorta works. I think. Its not very elegant though, I'm looking for something better.
func() {
echo "${#:1:$#-1}";
}
response=$(curl -s --write-out "%{http_code}" https://cat-fact.herokuapp.com/facts/random?animal=cat | jq .)
http_code=$(echo $response | awk '{print $NF}')
func $response | jq .
if [ $http_code == "503" ]; then
echo "Exiting with error due to 503"
exit 1
elif [ $http_code == "404" ]; then
echo "Exiting with error due to 404"
exit 1
fi
What about this. It uses a temporary file. Seems me a bit complicated but it separates your content.
# copy/paste doesn't work with the following
curl -s --write-out \
"%{http_code}" https://cat-fact.herokuapp.com/facts/random?animal=cat | \
tee test.txt | \ # split output to file and stdout
sed -e 's-.*\}--' | \ # remove everything before last '}'
grep 200 && \ # try to find string 200, only in success next step is done
echo && \ # a new-line to juice-up the output
cat test.txt | \ #
sed 's-}.*$-}-' | \ # removes the last line with status
jq # formmat json
Here a copy/paste version
curl -s --write-out "%{http_code}" https://cat-fact.herokuapp.com/facts/random?animal=cat | tee test.txt | sed -e 's-.*\}--' | grep 200 && echo && cat test.txt | sed 's-}.*$-}-' | jq
This is my attempt. Hope it works for you too.
#!/bin/bash
result=$( curl -i -s 'https://cat-fact.herokuapp.com/facts/random?animal=cat' )
status=$( echo "$result" | grep -E '^HTTPS?/[1-9][.][1-9] [1-9][0-9][0-9]' | grep -o ' [1-9][0-9][0-9] ')
payload=$( echo "$result" | sed -n '/^\s*$/,//{/^\s*$/ !p}' )
echo "STATUS : $status"
echo "PAYLOAD : $payload"
Output
STATUS : 200
PAYLOAD : {"_id":"591f98803b90f7150a19c23f","__v":0,"text":"Cats can't taste sweets.","updatedAt":"2018-12-05T05:56:30.384Z","createdAt":"2018-01-04T01:10:54.673Z","deleted":false,"type":"cat","source":"api","used":false}
AWK version
payload=$( echo "$result" | awk '{ if( $0 ~ /^\s*$/ ){ c_p = 1 ; next; } if (c_p) { print $0} }' )
Regards!
EDIT : I have simplified this even more by using the -i flag
EDIT II : Removed empty line from payload
EDIT III : Included an awk method to extract the payload in case sed is problematic
Borrowing from here you can do:
#!/bin/bash
result=$(curl -s --write-out "%{http_code}" https://cat-fact.herokuapp.com/facts/random?animal=cat)
http_code="${result: -3}"
response="${result:0:${#result}-3}"
echo "Response code: " $http_code
echo "Response: "
echo $response | jq
Where
${result: -3} is the 3rd index starting from the right of the string till the end. This ${result: -3:3} also would work: Index -3 with length 3
${#result} gives us the length of the string
${result:0:${#result}-3} from the beginning of result to the end minus 3 from the http_status code
The site cat-fact.herokuapp.com isn't working now so I had to test it with another site

sending multiple files as attachment in e-mail using mailx

I have a requiremnet to send multiple files as e-mail attachmnet in shell script. I have used below command.
(printf "%s\n" "BODY"; uuencode out.txt out.txt ; uuencode asgda.txt asgda.txt ) | mailx -m -s "TEST" emailid#domain.com
However the number of files i want to send as an attachmnet are dynamic. So I want to assign the uuencode ... comand to a variable and then use it. I have tried below way,
$ ATTACH_CMD=$(echo `cat $OUTPUT_FILE`)
$ echo $ATTACH_CMD
uuencode out.txt out.txt ; uuencode asgda.txt asgda.txt
$ (printf "%s\n" "BODY"; $ATTACH_CMD ) | mailx -m -s "TEST" emailid#domain.com
And i am getting below error.
sh: uuencode out.txt out.txt ; uuencode asgda.txt asgda.txt: not found.
Can any one please help me with this? Thanks in advance.
Have you tried using the below code? Not sure why it works, but maybe the below code could be used as a workaround
(printf "%s\n" "BODY"; `echo $ATTACH_CMD` ) | mailx -m -s "TEST" emailid#domain.com`?
For $ATTACH_CMD I have used echo command.
I finally found the way. eval makes the trick
eval $STR
$ ATTACH_CMD=$(echo `cat $OUTPUT_FILE`)
$ echo $ATTACH_CMD
uuencode out.txt out.txt ; uuencode asgda.txt asgda.txt
$ (printf "%s\n" "BODY"; eval $ATTACH_CMD ) | mailx -m -s "TEST" emailid#domain.com

Can't figure out how to send ^D (EOT) signal to mailx in bash script

I'm writing a bash script to send me an email automatically.
Mailx requires an EOT or ^D signal to know the message body is over and it can send.
I don't want to hit ^D on the keyboard when I run script which is what it does now.
Here is my code:
#! /bin/bash
SUBJ="Testing"
TO="test#test.com"
MSG="message.txt"
echo "I am emailing you" >> $MSG
echo "Time: `date` " >> $MSG
mail -s "$SUBJ" -q "$MSG" "$TO"
rm -f message.txt
If you do not need to add more text and just need to send the content of $MSG, you can replace
mail -s "$SUBJ" -q "$MSG" "$TO"
with
mail -s "$SUBJ" "$TO" < "$MSG"
The EOT will be implicit in the < construct. -q is indeed only used to start a message. The rest is supposed to come through stdin.
Pipe the output of a command group to mail.
#! /bin/bash
SUBJ="Testing"
TO="test#test.com"
MSG="message.txt"
{
echo "I am emailing you"
echo "Time: `date` "
} | mail -s "$SUBJ" -q "$MGS" "$TO"
rm -f message.txt

Sending simple message body + file attachment using Linux Mailx [duplicate]

This question already has answers here:
How to attach a file using mail command on Linux? [duplicate]
(13 answers)
Closed 5 years ago.
I am writing a shell script to send an email using Linux Mailx, the email must contain a file attachment and a message body.
Currently sending an email with an attachment:
output.txt | mail -s "Daily Monitoring" james#dell.com
I wish to add a message body. How should i?
Linux Mailx:
mail [-eIinv] [-a header] [-b addr] [-c addr] [-s subj] to-addr
The usual way is to use uuencode for the attachments and echo for the body:
(uuencode output.txt output.txt; echo "Body of text") | mailx -s 'Subject' user#domain.com
For Solaris and AIX, you may need to put the echo statement first:
(echo "Body of text"; uuencode output.txt output.txt) | mailx -s 'Subject' user#domain.com
The best way is to use mpack!
mpack -s "Subject" -d "./body.txt" "././image.png" mailadress
mpack - subject - body - attachment - mailadress
Johnsyweb's answer didn't work for me, but it works for me with Mutt:
echo "Message body" | mutt -s "Message subject" -a myfile.txt recipient#domain.com
Try this it works for me:
(echo "Hello XYX" ; uuencode /export/home/TOTAL_SI_COUNT_10042016.csv TOTAL_SI_COUNT_10042016.csv ) | mailx -s 'Script test' abc#xde.com
On RHEL Linux, I had trouble getting my message in the body of the email instead of as an attachment . Using od -cx, I found that the body of my email contained several /r. I used a perl script to strip the /r, and the message was correctly inserted into the body of the email.
mailx -s "subject text" me#yahoo.com < 'body.txt'
The text file body.txt contained the char \r, so I used perl to strip \r.
cat body.txt | perl success.pl > body2.txt
mailx -s "subject text" me#yahoo.com < 'body2.txt'
This is success.pl
while (<STDIN>) {
my $currLine = $_;
s?\r??g;
print
}
;
You can try this:
(cat ./body.txt)|mailx -s "subject text" -a "attchement file" receiver#domain.com

Resources