Sending mail from a Bash shell script

前端 未结 12 1493
梦毁少年i
梦毁少年i 2021-01-29 22:54

I am writing a Bash shell script for Mac that sends an email notification by opening an automator application that sends email out with the default mail account in Mail.app. The

相关标签:
12条回答
  • 2021-01-29 23:25

    Actually, "mail" works just as well.

    mail -s "subject line" name@address.ext < filename
    

    works perfectly fine, as long as you have SMTP set up on your machine. I think that most Macs do, by default.

    If you don't have SMTP, then the only thing you're going to be able to do is go through Mail.app. An ALTERNATIVE way to go through mail.app is via AppleScript. When you tell Mail.app to send mail via AppleScript you can tell it to not pop up any windows... (this does still require Mail.app to be configured).

    Introduction to Scripting Mail has a good description of how to work with mail in AppleScript.

    0 讨论(0)
  • 2021-01-29 23:26

    I whipped this up for the challenge. If you remove the call to 'dig' to obtain the mail relay, it is a 100% native Bash script.

    #!/bin/bash
    MAIL_FROM="sfinktah@bash.spamtrak.org"
    RCPT_TO="sfinktah@bash.spamtrak.org"
    MESSAGE=message.txt
    SMTP_PORT=25
    SMTP_DOMAIN=${RCPT_TO##*@}
    
    index=1
    while read PRIORITY RELAY
    do
        RELAY[$index]=$RELAY
        ((index++))
    done < <( dig +short MX $SMTP_DOMAIN )
    
    RELAY_COUNT=${#RELAY[@]}
    SMTP_COMMANDS=( "HELO $HOSTNAME" "MAIL FROM: <$MAIL_FROM>" "RCPT TO: <$RCPT_TO>" "DATA" "." "QUIT" )
    SMTP_REPLY=([25]=OK [50]=FAIL [51]=FAIL [52]=FAIL [53]=FAIL [54]=FAIL [55]=FAIL [45]=WAIT [35]=DATA [22]=SENT)
    
    for (( i = 1 ; i < RELAY_COUNT ; i++ ))
    do
        SMTP_HOST="${RELAY[$i]}"
        echo "Trying relay [$i]: $SMTP_HOST..."
        exec 5<>/dev/tcp/$SMTP_HOST/$SMTP_PORT
        read HELO <&5
        echo GOT: $HELO
        for COMMAND_ORDER in 0 1 2 3 4 5 6 7
        do
                OUT=${SMTP_COMMANDS[COMMAND_ORDER]}
                echo SENDING: $OUT
                echo -e "$OUT\r" >&5
    
                read -r REPLY <&5
                echo REPLY: $REPLY
                # CODE=($REPLY)
                CODE=${REPLY:0:2}
                ACTION=${SMTP_REPLY[CODE]}
                case $ACTION in
                        WAIT )          echo Temporarily Fail
                                                        break
                                                        ;;
                        FAIL )          echo Failed
                                                        break
                                                        ;;
                        OK )                            ;;
                        SENT )          exit 0
                                                        ;;
                        DATA )          echo Sending Message: $MESSAGE
                                                        cat $MESSAGE >&5
                                                        echo -e "\r" >&5
                                                        ;;
                        * )         echo Unknown SMTP code $CODE
                                                        exit 2
                esac
        done
    done
    
    0 讨论(0)
  • 2021-01-29 23:28

    Send mail from Bash with one line:

    echo "your mail body" | mail -s "your subject" yourmail@yourdomain.com -a "From: sender@senderdomain.com"
    
    0 讨论(0)
  • 2021-01-29 23:29

    Since Mac OS X includes Python, consider using a Python script instead of a Bash script. I haven't tested the sending portion, but it follows the standard example.

    Python script

    # Settings
    
    SMTP_SERVER = 'mail.myisp.com'
    SMTP_PORT = 25
    SMTP_USERNAME = 'myusername'
    SMTP_PASSWORD = '$uper$ecret'
    SMTP_FROM = 'sender@example.com'
    SMTP_TO = 'recipient@example.com'
    
    TEXT_FILENAME = '/script/output/my_attachment.txt'
    MESSAGE = """This is the message
    to be sent to the client.
    """
    
    # Now construct the message
    import smtplib, email
    from email import encoders
    import os
    
    msg = email.MIMEMultipart.MIMEMultipart()
    body = email.MIMEText.MIMEText(MESSAGE)
    attachment = email.MIMEBase.MIMEBase('text', 'plain')
    attachment.set_payload(open(TEXT_FILENAME).read())
    attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(TEXT_FILENAME))
    encoders.encode_base64(attachment)
    msg.attach(body)
    msg.attach(attachment)
    msg.add_header('From', SMTP_FROM)
    msg.add_header('To', SMTP_TO)
    
    # Now send the message
    mailer = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
    # EDIT: mailer is already connected
    # mailer.connect()
    mailer.login(SMTP_USERNAME, SMTP_PASSWORD)
    mailer.sendmail(SMTP_FROM, [SMTP_TO], msg.as_string())
    mailer.close()
    

    I hope this helps.

    0 讨论(0)
  • 2021-01-29 23:31

    sendEmail is a script that you can use to send email from the command line using more complicated settings, including connecting to a remote smtp server: http://caspian.dotconf.net/menu/Software/SendEmail/

    On OSX it is easily installable via macports: http://sendemail.darwinports.com/

    Below is the help page for the command, take note of the -s, -xu, -xp flags:

    Synopsis:  sendEmail -f ADDRESS [options]
    
    Required:
      -f ADDRESS                from (sender) email address
      * At least one recipient required via -t, -cc, or -bcc
      * Message body required via -m, STDIN, or -o message-file=FILE
    
    Common:
      -t ADDRESS [ADDR ...]     to email address(es)
      -u SUBJECT                message subject
      -m MESSAGE                message body
      -s SERVER[:PORT]          smtp mail relay, default is localhost:25
    
    Optional:
      -a   FILE [FILE ...]      file attachment(s)
      -cc  ADDRESS [ADDR ...]   cc  email address(es)
      -bcc ADDRESS [ADDR ...]   bcc email address(es)
    
    Paranormal:
      -xu USERNAME              authentication user (for SMTP authentication)
      -xp PASSWORD              authentication password (for SMTP authentication)
      -l  LOGFILE               log to the specified file
      -v                        verbosity, use multiple times for greater effect
      -q                        be quiet (no stdout output)
      -o NAME=VALUE             see extended help topic "misc" for details
    
    Help:
      --help TOPIC              The following extended help topics are available:
          addressing            explain addressing and related options
          message               explain message body input and related options
          misc                  explain -xu, -xp, and others
          networking            explain -s, etc
          output                explain logging and other output options
    
    0 讨论(0)
  • 2021-01-29 23:36

    Probably the only way you could do this, while keeping the program self-sufficient, is if you have direct access to an SMTP server from the clients.

    If you do have direct access to an SMTP server you can use the SMTP example from wikipedia and turn it into something like this:

    #!/bin/bash
    telnet smtp.example.org 25 <<_EOF
    HELO relay.example.org
    MAIL FROM:<joe@example.org>
    RCPT TO:<jane@example.org>
    DATA
    From: Joe <joe@example.org>
    To: Jane <jane@example.org>
    Subject: Hello
    
    Hello, world!
    .
    QUIT
    _EOF
    

    To handle errors I would redirect the output from telnet to a file and then grep that for a "success message" later. I am not sure what format the message should be, but I see something like "250 2.0.0 Ok: queued as D86A226C574" in the output from my SMTP server. This would make me grep for "^250.*queued as".

    0 讨论(0)
提交回复
热议问题