Отправка почты из оболочки 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 столкнуться с этой проблемой.
Ответы
Ответ 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. Его довольно полный отправитель электронной почты, полностью автономный.