Search code examples
linuxbashraspberry-pissmtp

Problem sending variables to email using Bash and ssmtp


I am trying to send an email using Bash and ssmtp. I have gathered the login data from the /var/log/auth.log file and generated the email content. However, when I try to send the email, the variables are not being sent.

Here is the script I am using:

#!/bin/bash

# Gather login data
login_data=$(journalctl -u dropbear.service | grep "Password")

# Generate email content
email_content="Login Data:\n${login_data}"

# Send email using ssmtp
sync
ssmtp -m [email protected] < <(echo "${email_content}")

I have tried using the flush command instead of the sync command, but it does not make a difference. I have also tried using the wait command to wait for the ssmtp command to exit before exiting the script, but it does not make a difference either.

I have also tried using the mail command instead of the ssmtp command, and it works

echo "${email_content}" | mail -s "hey" "[email protected]"

I am it happy it works with mail, but i want to understand better the ssmtp command, I read is more reliable

I found a similar question on Stack Overflow, but the solution is not related: ssmtp cannot email my bash variable received from python subprocess

Operating system: dietpi

Details:

  • The message using ssmtp is completely empty, not even the label "login data"

  • Echoing the \n does not make a new line. The mail send with the mail command change line with the \n

  • Output using set -x at the top:

    Nov 07 19:48:18 DietPi dropbear[15323]: [15323] Nov 07 19:48:18 Password auth succeeded for '\''root'\'' from ip:12342
    Nov 07 22:56:28 DietPi dropbear[18942]: [18942] Nov 07 22:56:28 Password auth succeeded for '\''root'\'' from from ip:12342
    Nov 08 10:59:19 DietPi dropbear[24025]: [24025] Nov 08 10:59:19 Password auth succeeded for '\''root'\'' from from ip:12342
    Nov 08 19:14:44 DietPi dropbear[30112]: [30112] Nov 08 19:14:44 Password auth succeeded for '\''root'\'' from from ip:12342
    
  • The script is run in bash. version: 5.2.15(1)-release

  • echo -e does not make a change.

I think the problem lies in the sstmp command. The mail function works good with the same echo command

echo  "$failed_login" | mail -s "failed" "[email protected]"

ssmtp without the variable sends text:

echo  "login_data" | ssmtp - m [email protected]

Solution

  • The input to ssmtp should be a well-formed RFC5322 message, not some random string data. Try this:

    ssmtp - m [email protected] <<____here
    Subject: no subject
    From: yourself <[email protected]>
    To: recipient <[email protected]>
    
    $email_content
    ____here
    

    Collecting the output in a string variable just so you can then immediately interpolate it back once is just a waste of memory; here is a more efficient approach.

    ( printf '%s\n' "Subject: Login data" \
        "From: yourself <[email protected]>" \
        "To: recipient <[email protected]>" \
        "" \
        "Login Data:"
        journalctl -u dropbear.service | grep "Password"
    ) | ssmtp -m [email protected]
    

    Generally, you don't want to piece together email messages from pieces of string if you can avoid it; there are many corner cases where you need a deep understanding of the relevant RFCs and MIME standards etc.

    sync has nothing to do with this; it (requires root and) writes out any pending disk writes to your hard drive.

    Also, \n in a string is just \n; but e.g. printf interprets this and a number of other escape codes. Bash also has $'C-style strings\nwhere\tthis\a works' and echo -e (but probably prefer printf which is more portable as well as more elegant and versatile).

    Some mail servers will assume that you have empty headers and artificially add an empty line (or syntesized headers) above the message you provide when it is obviously malformed, but this isn't reliable (and "obviously malformed" typically means "does not have a colon immediately after the first token" which surprisingly often your malformed message will also have; for example, that was the problem with the near-duplicate question you found).