0

using ksh on an AIX 7.2 system

I have the following inputfile:

line1   
line2  
line3

I have the following code (rather simplified)

cat infile | while read strA ; do  
    echo "strA: $strA"  
    mail -s"check script strA: $strA" me@mailserver.com  
done  

"mail" seems to read from STDIN, what stops the loop after the first line.
Result is:

line1  
=>sending mail

When I let "mail" read from /dev/null, it works:

mail -s"check script strA: $strA" me@mailserver.com </dev/null  

BUT this way I get Warnings "No Message Body"

When I give a not empty dummyfile it also works`

   mail -s"check script strA: $strA" me@mailserver.com </tmp/anyexistingfile  

BUT I do not want to send some rubbish

Is there another way to prevent reading from STDIN and exiting the loop?
Any secret mail-option? (I can't find some)

Thank you very much in advance

(hmmm ... took me 10 minutes to describe the problem and 20 minutes to format the text)

Kusalananda
  • 333,661
Rudi
  • 1
  • It's unclear what you actually want to send in those emails. – Kusalananda Aug 10 '21 at 05:54
  • 1
    You can always do echo See subject. | mail.... Or even echo | mail... to make the body an empty line. – Stéphane Chazelas Aug 10 '21 at 05:54
  • BTW, the syntax to read a line in ksh is IFS= read -r line, and to print arbitrary data: print -r -- "$data". Without those -r (or with echo), backslash characters receive a special treatment. – Stéphane Chazelas Aug 10 '21 at 05:59
  • @Kusanalanda: The example is very much simplified. I loop over the input file. On some strings found, I want to start something, on some strings I want to calculate something and on certain conditions I want to send a warning by email. The warning does not need much text (message body), it's enough to describe the Warning in the subject field. – Rudi Aug 10 '21 at 06:23
  • @Stéphane Chazelas
    about syntax: Thank you for that tip. But in 20 years I always used "cat file | while read ...." without ever having a problem.
    – Rudi Aug 10 '21 at 06:26
  • @Stéphane Chazelas - about your solution with "echo | mail ...": Oh WOW, It's so simple? Waht a shame that I did not found by myself. Thank you very much, your solution works absolutely perfect for me :-) – Rudi Aug 10 '21 at 06:28
  • Then I take it you've never processed input containing backslashes or starting or ending with space or tabs (and wanting to preserve them) assuming an unmodified IFS or ending in a character of IFS. – Stéphane Chazelas Aug 10 '21 at 06:29
  • Also note that the standard command (though optional) for sending email is mailx. mail is not a standard command. Some systems have one (or sometimes a Mail one) though not all support a -s option to set the subject. – Stéphane Chazelas Aug 10 '21 at 06:30

1 Answers1

1

Yes, mail (or preferably the standard mailx), when in send mode, reads the body of the email to send from stdin.

You generally don't want to send empty emails. More often than not, an empty body is a sign something went wrong which is why your mail command gives you that warning.

I don't know if AIX mail command has a way to disable that warning (though you could discard it along with any other warning or error message with 2> /dev/null), but alternatively, you could send a minimal body such as See subject. or an empty line with:

echo See subject. | mailx...
echo | mailx...

So, putting it all together:

while IFS= read <&3 -r strA ; do  
  printf 'strA: "%s"\n' "$strA"  
  echo | mailx -s"check script strA: $strA" me@mailserver.example.com  
done 3< infile

Opening infile on fd 3 (which contrary to 0, 1, 2 is not special), instead of fd 0 also makes sure commands in the loop won't read from it.

See also: