J'écris un Bash Script Shell pour Mac qui envoie une notification par e-mail en ouvrant une application d'automatisme qui envoie des e-mails avec le compte de messagerie par défaut dans Mail.app. L'application d'automatisation joint également un fichier texte sur lequel le script a écrit. Les problèmes avec cette solution sont
Je pense que pour contourner ces lacunes, je devrais envoyer le courrier directement à partir du script en entrant SMTP paramètres, adresse à envoyer, etc. directement dans le script. Le hic, c'est que je voudrais déployer ce script sur plusieurs ordinateurs (10.5 et 10.6) sans activer Postfix sur l'ordinateur. Est-il possible de le faire dans le script afin qu'il s'exécute sur une installation de base de Mac OS X de 10,5. et 10,6?
Mise à jour: j'ai trouvé le -bs
option pour Sendmail qui semble être ce dont j'ai besoin, mais je ne sais pas comment spécifier les paramètres.
De plus, pour clarifier, la raison pour laquelle je voudrais spécifier les paramètres SMTP est que les e-mails de l'hôte local sur le port 25 envoyés via Postfix seraient bloqués par la plupart des pare-feu d'entreprise, mais si je spécifie le serveur et un port alternatif, je ne fonctionnerai pas dans ce problème.
Étant donné que Mac OS X inclut Python, envisagez d'utiliser un script Python au lieu d'un script Bash. Je n'ai pas testé la partie d'envoi, mais elle suit le exemple standard .
# 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()
J'espère que ça aide.
En fait, le "courrier" fonctionne aussi bien.
mail -s "subject line" [email protected] < filename
fonctionne parfaitement, tant que SMTP est configuré sur votre machine. Je pense que la plupart des Mac le font, par défaut.
Si vous ne disposez pas de SMTP, la seule chose que vous pourrez faire est de passer par Mail.app. Une manière ALTERNATIVE de passer par mail.app est via AppleScript . Lorsque vous dites à Mail.app d'envoyer du courrier via AppleScript, vous pouvez lui dire de ne pas faire apparaître de fenêtre ... (cela nécessite toujours la configuration de Mail.app).
Introduction to Scripting Mail a une bonne description de la façon de travailler avec le courrier dans AppleScript.
Il existe un programme appelé Sendmail .
Vous ne voulez probablement pas utiliser le -bs
à moins que vous ne l'envoyiez en SMTP brut comme l'exemple de Martin. -bs
sert à exécuter un serveur SMTP en tant que démon. Sendmail enverra directement au serveur de messagerie récepteur (sur le port 25), sauf si vous le remplacez dans le fichier de configuration. Vous pouvez spécifier le fichier de configuration par le -C
paramètre.
Dans la configuration, vous pouvez spécifier un serveur relais (tout serveur de messagerie ou sendmail exécutant -bs
sur une autre machine)
L'utilisation d'un serveur de relais correctement configuré est une bonne idée car lorsque le service informatique gère des serveurs de messagerie, il implémente SPF et clés de domaine . Cela garde votre courrier hors de la poubelle.
Si le port 25 est bloqué, vous avez deux options.
sendmail -bd
sur une machine en dehors du pare-feu d'entreprise qui écoute sur un port autre que 25.Je pense que vous pouvez ajouter des paramètres de configuration sur la ligne de commande. Ce que vous voulez, c'est l'option SMART_Host. Appelez donc Sendmail comme sendmail -OSMART_Host=nameofhost.com
.
La seule façon de le faire, tout en conservant le programme autosuffisant, est probablement si vous avez un accès direct à un serveur SMTP à partir des clients.
Si vous avez un accès direct à un serveur SMTP, vous pouvez utiliser exemple SMTP de wikipedia et le transformer en quelque chose comme ceci:
#!/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
Pour gérer les erreurs, je redirigerais la sortie de telnet vers un fichier, puis je le grepais pour un "message de réussite" plus tard. Je ne suis pas sûr du format du message, mais je vois quelque chose comme "250 2.0.0 Ok: mis en file d'attente en tant que D86A226C574" dans la sortie de mon serveur SMTP. Cela me ferait grpper pour "^ 250. * en file d'attente comme".
sendEmail est un script que vous pouvez utiliser pour envoyer des e-mails à partir de la ligne de commande en utilisant des paramètres plus compliqués, y compris la connexion à un serveur smtp distant: http://caspian.dotconf.net/menu/Software/SendEmail/ =
Sur OSX, il est facilement installable via macports: http://sendemail.darwinports.com/
Ci-dessous la page d'aide de la commande, notez les drapeaux -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
Envoyez du courrier de Bash avec une seule ligne:
echo "your mail body" | mail -s "your subject" [email protected] -a "From: [email protected]"
Voici un simple script Ruby pour ce faire. Ruby est livré avec les versions de Mac OS X que vous avez mentionnées.
Remplacez tous les bits marqués "remplacer". S'il échoue, il renvoie un code de sortie différent de zéro et une trace arrière 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!')
Vous pouvez intégrer cela dans un script Bash comme ceci:
Ruby << EOF
... script here ...
EOF
Pour d'autres façons d'envoyer des courriels Ruby, voir la question Stack Overflow Comment envoyer du courrier à partir d'un programme Ruby?.
Vous pouvez également utiliser d'autres langues fournies avec Mac OS X:
Je l'ai préparé pour le défi. Si vous supprimez l'appel à "Dig" pour obtenir le relais de messagerie, il s'agit d'un script Bash 100% natif.
#!/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
sendmail
et même postfix
peuvent être trop gros à installer si tout ce que vous voulez faire est d'envoyer quelques e-mails à partir de vos scripts.
Si vous avez un compte Gmail par exemple, vous pouvez utiliser les serveurs de Google pour envoyer des e-mails en utilisant SMTP . Si vous ne souhaitez pas utiliser le serveur de gGoogle, tant que vous avez accès à un serveur SMTP, cela devrait fonctionner.
Un programme très léger qui le rend facile à faire est msmtp . Ils ont exemples de fichiers de configuration dans leur documentation .
La façon la plus simple de le faire serait de configurer une valeur par défaut à l'échelle du système:
account default
Host smtp.gmail.com
from [email protected]
user [email protected]
password XXX
port 587
msmtp
devrait être très facile à installer. En fait, il y a n port pour cela, donc ça pourrait être aussi simple que port install msmtp
.
Après avoir installé et configuré msmtp
, vous pouvez envoyer un e-mail à [email protected]
en utilisant:
mail -s <subject> [email protected] <<EOF
<mail text, as many lines as you want. Shell variables will be expanded>.
EOF
Vous pouvez mettre ce qui précède dans un script. Voir man mail
pour plus de détails.
1) Pourquoi ne pas configurer postfix
pour gérer uniquement le courrier sortant et le relayer via une passerelle de messagerie? Son plus grand avantage est qu'il est déjà installé sur les clients OS X.
2) Installez et configurez l'un des MTA légers qui ne gèrent que le courrier sortant, comme nullmailer
ou ssmtp
(disponible via MacPorts).
Dans les deux cas, utilisez mailx(1)
(ou mutt
si vous voulez faire preuve de fantaisie) pour envoyer les e-mails à partir d'un script Shell.
Il y a plusieurs questions sur la défaillance du serveur qui entrent dans les détails.
Voici un extrait de script shells modifié que j'ai utilisé sur divers systèmes UNIX ... (echo "${MESSAGE}" | ${uuencode} ${ATTACHMENT}
$ basename $ {ATTACHMENT} ) | ${mailx} -s "${SUBJECT}" "${TO_LIST}"
uuencode et mailx sont définis sur les exécutables. Les autres variables proviennent d'une entrée utilisateur analysée à l'aide de getopts.
Cela fonctionne, mais je dois admettre le plus souvent que j'utilise un simple programme Java pour envoyer des e-mails sur la console).
Essayez mtcmail. C'est un expéditeur d'e-mails assez complet, complètement autonome.