Seite 1 von 1
mail auf unix funktioniert nicht richtig
Verfasst: Mittwoch 20. Juli 2011, 09:12
von patmaster
Hi,
Da bei uns ständig die Server den Geist aufgeben und es keiner mitbekommt, dachte ich mir ich schreibe ein kleines Script, das uns darüber in Kenntnis setzt:
hostnames ist eine Liste aus Paaren, die aus IP und Servername bestehen, die ich hier mal zensiert habe
Code: Alles auswählen
import subprocess
hostnames = [("xx.xx.xx.xx","XXXXXXXX" ), ....]
for host in hostnames:
ret = subprocess.call("ping -c 1 %s" % host[0], shell=True, stdout=open("/dev/null", "w"),stderr=subprocess.STDOUT)
if ret == 0:
print "%s is alive" % host[1]
mailstring = "%s is alive" % host[1]
cmd = ["mail -s 'Test' test.test@test.at"]
subprocess.call(cmd,shell=True)
else:
print "%s is dead" % host[1]
Mein Problem ist nun, dass beim senden der Mail das Script anscheinend hängen bleibt. Sobald ich das Script aber kille, bekomme ich die Mail.
Ich bin noch Anfänger und verwende vermutlich subprocess falsch.
Kann mich bitte jemand aufklähren ?!
Re: mail auf unix funktioniert nicht richtig
Verfasst: Mittwoch 20. Juli 2011, 09:20
von deets
Du koennstest schonmal damit anfangen, deine Postings in den dafuer vorgesehenen Unterforen zu machen. Oder entgeht mir hier die Verbindung zu Grafikprogrammierung?
Danach wuerde ich dir mal empfehlen, statt suprocess zum Versand von mails lieber die Python-eigene smtplib zu verwenden. Da gibt es genug Beispiele.
Dann benutzt du subprocess eher...ungewoehnlich. Entweder ist cmd ein String, oder eine Liste - wenn letzteres, dann aber mit den einzelnen Komponenten, also
["mail", "-s", ...]
Ich bin mir im Moment nicht sicher, ob dann shell-expansion noch funktioniert, aber ich sehe auch keinen Grund dafuer, warum du shell=True uberehaupt verwendest.
Last but not least: mail nimmt den Mail-Body ueber die Standardeingabe entgegen, du gibst ihm aber nichts. Das koennte dein Verhalten erklaeren.
Re: mail auf unix funktioniert nicht richtig
Verfasst: Mittwoch 20. Juli 2011, 09:23
von patmaster
sry, das mit dem Forum war nen versehen -.-
Danke für die Tipps !
Re: mail auf unix funktioniert nicht richtig
Verfasst: Mittwoch 20. Juli 2011, 13:03
von cofi
Was spricht dagegen Standardsoftware wie z.b. Nagios zu nutzen? Das ist jetzt nun wirklich kein aussergewoehnliches Problem, dass das selbst schreiben rechtfertigt
Zur Benutzung von `subprocess` gibt es in der Doku und auch hier im Forum jede Menge Beispiele.
Re: mail auf unix funktioniert nicht richtig
Verfasst: Mittwoch 20. Juli 2011, 21:12
von Drache
Mmmh, hilft dir der (ungetestete) Code Fetzen weiter ?
Code: Alles auswählen
import email
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.Utils import formatdate
if deine_bedinung == True:
oNachricht = MIMEMultipart()
oNachricht['From'] = 'deine_mail@dein_email_account.de'
oNachricht['To'] = 'seine_mail@dein_email_account.de'
oNachricht['Date'] = formatdate(localtime= True)
oNachricht['Subject'] = "oh Oh"
server = smtplib.SMTP('mail.dein_email_account.de')
server.ehlo()
server.login('deine_mail','topsecret')
server.starttls()
server.ehlo()
server.sendmail(oNachricht['From'], oNachricht['To'],oNachricht.as_string())
server.quit()
print("email versendet\n ")
Drache
Re: mail auf unix funktioniert nicht richtig
Verfasst: Donnerstag 21. Juli 2011, 06:57
von patmaster
Danke Drache, aber ich hab das mittlerweile mit mail von Linux hinbekommen:
Code: Alles auswählen
#imports
import subprocess, time
#variables
hostnames = [("xx.xx.xx.xx","XXXXXXXXX" ), ....]
recips = ["xx.xx@xx.xx",...]
logstring = ""
mail = 0
#for all hosts
for host in hostnames:
#certain hosts need diffrent treatment (nmap instead of ping)
#ping
if host[0] != "xx.xx.xx.xx":
ret = subprocess.call("ping -c 1 %s" % host[0], shell=True, stdout=open("/dev/null", "w"),stderr=subprocess.STDOUT)
if ret == 0:
logstring += "%s seems to be alive \n" % host[1]
else:
logstring += "%s seems to be dead !!! \n" % host[1]
mail += 1
#nmap
else:
ret = subprocess.Popen("nmap -p 8000 %s" % host[0],shell=True,stdout=subprocess.PIPE)
if "8000/tcp open" in ret.communicate()[0]:
logstring += "%s seems to be alive \n" % host[1]
else:
logstring += "%s seems to be dead !!! \n" % host[1]
mail +=1
#send a mail if we los a Server
if mail > 0:
for recip in recips:
subprocess.call("echo '%s' | mail -s 'Serverstatus' %s" % (logstring,recip), shell=True)
#write log anyway
with open("/home/technik/windowsmount/Produktion/Serverstatus/pinger_log.txt", "w") as log:
lt = time.localtime()
jahr, monat, tag, stunde, minute, sekunde = lt[0:6]
log.write("Checked Serverstatus at %02i.%02i.%04i - %02i:%02i:%02i \n" % (tag,monat,jahr,stunde,minute,sekunde))
log.write("-------------------------------------------------------- \n")
log.write(logstring)
Bin dankbar für konstruktives feedback.
Ich nehme an es gibt ne bessere möglichkeit die mail an mehrere Leute zu versenden, aber auf die schnelle habe ich die richtige Syntax nicht gefunden...
Re: mail auf unix funktioniert nicht richtig
Verfasst: Donnerstag 21. Juli 2011, 09:07
von deets
Mindestens mal solltest du dir subprocess nochmal anschauen, und statt "call" "Popen" verwenden - da kannst du naemlich die standardeingabe von mail einfach mit einem String beschicken, via Popen.stdin.write(message).
Aber noch besser ist die von mir & Drache vorgeschlagene Moeglichkeit, mails direkt zu versenden, und die "Syntax" dafuer wurde dir ja schon praesentiert.
Re: mail auf unix funktioniert nicht richtig
Verfasst: Donnerstag 21. Juli 2011, 09:12
von patmaster
alles klar, werde mir das ganze per Gelegenheit noch mal ansehen.
Vlt. kommt ja davon auch noch was in dem Python-Buch das ich gerade lese

Re: mail auf unix funktioniert nicht richtig
Verfasst: Donnerstag 21. Juli 2011, 09:28
von Whitie
Hallo patmaster,
evtl. könnte man für das ganze Skript auch das
logging Modul verwenden. Ein FileHandler und ein SMTPHandler.
Gruß Whitie
Edit: Hier mal ein kleines (ungetestetes) Beispiel
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import os
import subprocess
from logging.handlers import RotatingFileHandler, SMTPHandler
HOSTS = (('xx.xx.xx.xx', 'XXXX'), ('yy.yy.yy.yy', 'YYYYY'))
RECIPIENTS = ['admin1(at)example.org', 'admin2(at)example.org']
def create_logger():
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
file_handler = RotatingFileHandler('/path/to/logfile.log',
maxBytes=1000*1000, backupCount=7)
smtp_handler = SMTPHandler('smtp.example.org', 'sender(at)example.org',
RECIPIENTS, 'Serverstatus')
smtp_handler.setLevel(logging.ERROR)
formatter = logging.Formatter('[%(asctime)s] %(levelname)s: %(message)s',
'%d.%m.%Y - %H:%M:%S')
file_handler.setFormatter(formatter)
smtp_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.addHandler(smtp_handler)
return logger
def main():
log = create_logger()
for ip, name in HOSTS:
try:
subprocess.check_call(['ping', '-c', '3', ip],
stdout=open(os.devnull, 'w'), stderr=subprocess.STDOUT)
log.info('%s seems to be alive', name)
except subprocess.CalledProcessError:
log.error('%s seems to be dead!', name)
if __name__ == '__main__':
main()