Подтвердить что ты не робот

Отправка почты из оболочки Bash script

Я пишу Bash shell script для Mac, который отправляет уведомление по электронной почте, открывая приложение-автомат, отправляющее электронную почту с помощью учетная запись электронной почты по умолчанию в Mail.app. Приложение-автомат также прикрепляет текстовый файл, который написал script. Проблемы с этим решением:

  • Он отображается в графическом интерфейсе при отправке
  • Он крадет фокус, если Mail не является текущим приложением
  • Это зависит от настройки учетной записи Mail.app, действующей в будущем

Я считаю, что обойти эти недостатки я должен отправить почту непосредственно из script, введя настройки SMTP, адрес для отправки, и т.д. непосредственно в script. Уловкой я хотел бы развернуть этот script на нескольких компьютерах (10.5 и 10.6) без включения Postfix на компьютере. Возможно ли это сделать в script, поэтому он будет работать на базовой Mac OS X nbsp 10 X 10.5. и 10,6?

Обновление: я нашел параметр -bs для Sendmail, который, похоже, мне нужен, но я не понимаю, как указать настройки.

Кроме того, чтобы уточнить, причиной, по которой я хотел бы указать параметры SMTP, является то, что письма с localhost на порт 25, отправленные через Postfix, будут блокироваться большинством корпоративных брандмауэров, но если я укажу сервер и альтернативный порт, я выиграл 't столкнуться с этой проблемой.

4b9b3361

Ответ 1

Так как Mac X X включает Python, рассмотрите возможность использования Python script вместо Bash script. Я не тестировал отправляющую часть, но она следует за стандартным примером .

Python script

# Settings

SMTP_SERVER = 'mail.myisp.com'
SMTP_PORT = 25
SMTP_USERNAME = 'myusername'
SMTP_PASSWORD = '$uper$ecret'
SMTP_FROM = '[email protected]'
SMTP_TO = '[email protected]'

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()

Надеюсь, это поможет.

Ответ 2

Собственно, "почта" работает так же хорошо.

mail -s "subject line" [email protected] < filename

работает отлично, если на вашем компьютере установлена ​​SMTP. Я думаю, что большинство компьютеров Mac по умолчанию.

Если у вас нет SMTP, то единственное, что вы собираетесь сделать, это пройти через Mail.app. АЛЬТЕРНАТИВНЫЙ способ перехода через mail.app через AppleScript. Когда вы скажете Mail.app отправлять почту через AppleScript, вы можете сказать ей, чтобы она не открывала никаких окон... (это все еще требует настройки Mail.app).

Введение в Scripting Mail содержит хорошее описание того, как работать с почтой в AppleScript.

Ответ 3

Существует программа под названием Sendmail.

Вероятно, вы не хотите использовать команду -bs, если вы не отправляете ее как необработанный SMTP, такой как пример Мартина. -bs предназначен для запуска SMTP-сервера в качестве деамона. Sendmail отправит непосредственно на принимающий почтовый сервер (на порт 25), если вы не переопределите его в файле конфигурации. Вы можете указать файл конфигурации с помощью параметра -C.

В конфигурации вы можете указать сервер ретрансляции (любой почтовый сервер или sendmail, выполняющий -bs на другой машине)

Использование правильно настроенного сервера ретрансляции - хорошая идея, потому что, когда ИТ управляет почтовыми серверами, они реализуют SPF и ключи домена. Это избавляет вашу почту от мусорного бака.

Если порт 25 заблокирован, вы остаетесь с двумя параметрами.

  • Использовать корпоративный SMTP-сервер.
  • Запустите sendmail -bd на машине вне корпоративный брандмауэр, который слушает на порту, отличном от 25.

Я полагаю, вы можете добавить параметры конфигурации в командной строке. Вы хотите использовать SMART_HOST. Поэтому вызовите Sendmail как sendmail -OSMART_HOST=nameofhost.com.

Ответ 4

Вероятно, единственный способ сделать это, сохраняя при этом программу самодостаточной, - это прямой доступ к SMTP-серверу от клиентов.

Если у вас есть прямой доступ к SMTP-серверу, вы можете использовать SMTP-пример из википедии и превратить его в нечто вроде этого:

#!/bin/bash
telnet smtp.example.org 25 <<_EOF
HELO relay.example.org
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
From: Joe <[email protected]>
To: Jane <[email protected]>
Subject: Hello

Hello, world!
.
QUIT
_EOF

Чтобы обрабатывать ошибки, я перенаправлял вывод из telnet в файл, а затем grep, что для сообщения об успешном завершении. Я не уверен, в каком формате должно быть сообщение, но я вижу что-то вроде "250 2.0.0 Ok: поставлен в очередь как D86A226C574" на выходе моего SMTP-сервера. Это сделало бы меня grep для "^ 250. * в очереди как".

Ответ 5

sendEmail - это script, который можно использовать для отправки электронной почты из командной строки с использованием более сложных параметров, включая подключение к удаленному SMTP-серверу: http://caspian.dotconf.net/menu/Software/SendEmail/

В OSX он легко устанавливается через macports: http://sendemail.darwinports.com/

Ниже приведена страница справки для команды, обратите внимание на флаги -s, -xu, -xp:

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

Ответ 6

Отправляйте почту из Bash с помощью одной строки:

echo "your mail body" | mail -s "your subject" [email protected] -a "From: [email protected]"

Ответ 7

Вот простой Ruby script, чтобы сделать это. Рубиновые корабли на Mac OS X n, которые вы упомянули.

Замените все биты с надписью "replace". Если он терпит неудачу, он возвращает ненулевой код выхода и обратную трассировку Ruby.

require 'net/smtp'

SMTPHOST = 'replace.yoursmtpserver.example.com'
FROM = '"Your Email" <[email protected]>'

def send(to, subject, message)
  body = <<EOF
From: #{FROM}
To: #{to}
Subject: #{subject}

#{message}
EOF
  Net::SMTP.start(SMTPHOST) do |smtp|
    smtp.send_message body, FROM, to
  end
end

send('[email protected]', 'testing', 'This is a message!')

Вы можете вставить это в Bash script так:

ruby << EOF
 ... script here ...
EOF

Другие способы отправки писем Ruby см. в разделе Вопрос Как отправить почту из программы Ruby?.

Вы можете использовать другие языки, которые поставляются с Mac OS X:

Ответ 8

Я взбесил это на вызов. Если вы удалите вызов "dig" для получения почтового ретранслятора, это 100% -ный родной Bash script.

#!/bin/bash
MAIL_FROM="[email protected]"
RCPT_TO="[email protected]"
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

Ответ 9

1) Почему бы не сконфигурировать postfix только для обработки исходящей почты и передать ее через почтовый шлюз? Его самым большим преимуществом является то, что он уже установлен на клиентах OS X.

2) Установите и настройте один из облегченных MTA, которые обрабатывают только исходящую почту, например nullmailer или ssmtp (доступны через MacPorts).

В обоих случаях используйте mailx(1) (или mutt, если вы хотите получить фантазию) для отправки писем из оболочки script.

Есть несколько вопросов о сбое сервера, которые входят в детали.

Ответ 10

sendmail и даже postfix может быть слишком большим для установки, если все, что вы хотите сделать, - отправить несколько писем из ваших скриптов.

Если у вас есть Gmail, вы можете использовать серверы Google для отправки электронной почты с помощью SMTP. Если вы не хотите использовать gGoogle-сервер, если у вас есть доступ к некоторому SMTP-серверу, он должен работать.

Очень легкая программа, облегчающая это, msmtp. Они примеры файлов конфигурации в своей документации.

Самый простой способ сделать это - установить системное значение по умолчанию:

account default
host smtp.gmail.com
from [email protected]
user [email protected]
password XXX
port 587

msmtp должен быть очень прост в установке. Фактически для него есть порт, поэтому это может быть так же просто, как port install msmtp.

После установки и настройки msmtp вы можете отправить электронное письмо на адрес [email protected], используя:

mail -s <subject> [email protected] <<EOF
<mail text, as many lines as you want. Shell variables will be expanded>.
EOF

Вы можете положить выше в script. Подробнее см. man mail.

Ответ 11

Здесь измененные оболочки script snip, которые я использовал в различных UNIX-системах... (echo "${MESSAGE}" | ${uuencode} ${ATTACHMENT} $basename ${ATTACHMENT} ) | ${mailx} -s "${SUBJECT}" "${TO_LIST}"

uuencode и mailx установлены в исполняемые файлы. Другие переменные от пользователя вводятся с использованием getopts.

Это работает, но я должен признаться чаще, чем я, я использую простую программу Java для отправки электронных писем в консоли.

Ответ 12

Попробуйте mtcmail. Его довольно полный отправитель электронной почты, полностью автономный.