Seite 1 von 2

Mailversand per os.system()

Verfasst: Dienstag 8. Januar 2019, 18:58
von Mesquita
Hallo User,

ich möchte aus einem Skript heraus eine Mail versenden. Dazu teste ich gerade folgenden Code:

Code: Alles auswählen

os.system('echo “Inhalt der Mail” | mail -s “Betreff der Mail” empfaengeradresse')
Der Mailversand funktioniert von der Konsole und aus dem Skript heraus. Der Sinn der Mail soll aber sein, dass der Inhalt einer Variable (Sting) aus dem Skript versendet wird. Wie kann ich den Inhalt der String-Variable mittels mail als Inhalt der Mail versenden? Ich recherchierte, fand aber keinen Ansatz.

Thomas

Re: Mailversand per os.system()

Verfasst: Dienstag 8. Januar 2019, 19:35
von __blackjack__
`os.system()` sollte man sowieso nicht mehr verwenden, in der Dokumentation wird auch auf das `subprocess`-Modul verwiesen. Und da kannst Du die `run()`-Funktion verwenden. Ungetestet:

Code: Alles auswählen

subprocess.run(['mail', '-s', 'Betreff der Mail', 'empfängeradresse'], input='Inhalt der Mail', check=True)

Re: Mailversand per os.system()

Verfasst: Mittwoch 9. Januar 2019, 16:08
von Mesquita
Hallo blackjack,

danke für Deine Antwort. Sobald ich das Modul subprocess:

Code: Alles auswählen

subprocess.run(['mail', '-s', 'Betreff der Mail', '***@***.com'], input='Inhalt der Mail', check=True)

einbinde, kommt folgende Fehlermeldung:

Code: Alles auswählen

subprocess.run(['mail', '-s', 'Betreff der Mail', '***@***.com'], input='Inhalt der Mail', check=True)
AttributeError:'module' object has no attribute 'run'
Sollte es an der Python 2.7.13 liegen oder warum findet er "run" nicht?

Thomas

Re: Mailversand per os.system()

Verfasst: Mittwoch 9. Januar 2019, 16:23
von __deets__
Ja, das ist eine alte Python-Version. Du solltest tatsaechlich auf Python3 umsteigen.

Re: Mailversand per os.system()

Verfasst: Mittwoch 9. Januar 2019, 17:03
von __blackjack__
Unter Python 2.7 musst Du ein `Popen`-Objekt erstellen, die Standardeingabe als Pipe definieren und den Inhalt dann über die `communicate()`-Methode übergeben.

Re: Mailversand per os.system()

Verfasst: Mittwoch 9. Januar 2019, 17:07
von Mesquita
Guten Abend,

die Umstellung auf Python3 habe ich vorghenommen. Das Ergebnis beim gleichen Aufruf ist:

Code: Alles auswählen

subprocess.run('mail', '-s', 'Betreff', '***@***', input='Hier soll der Inhalt der Variable stehen', check=True)
  File "/usr/lib/python3.5/subprocess.py", line 383, in run
    with Popen(*popenargs, **kwargs) as process:
TypeError: __init__() got multiple values for argument 'stdin'
Handelt es sich um einen Syntaxfehler in der Standardeingabe stdin?

Thomas

Re: Mailversand per os.system()

Verfasst: Mittwoch 9. Januar 2019, 17:10
von Mesquita
Hallo blackjack,

ich würde gern mit Python3 weiterarbeiten, da habe ich auch Unterlagen/Bücher/Lehrmaterial dazu.

Thomas

Re: Mailversand per os.system()

Verfasst: Mittwoch 9. Januar 2019, 17:53
von Sirius3
Schau mal genau, was __blackjack__ geschrieben hat. Außerdem sollte input noch binär sein, oder ein encoding= angegeben werden.

Re: Mailversand per os.system()

Verfasst: Donnerstag 10. Januar 2019, 18:39
von Mesquita
Hallo blackjack,

trifft dies auch für Python 3.5 zu?
__blackjack__ hat geschrieben: Mittwoch 9. Januar 2019, 17:03 Unter Python 2.7 musst Du ein `Popen`-Objekt erstellen, die Standardeingabe als Pipe definieren und den Inhalt dann über die `communicate()`-Methode übergeben.
Thomas

Re: Mailversand per os.system()

Verfasst: Freitag 11. Januar 2019, 01:40
von __deets__
Dafür gibt es subprocess.run, wie ursprünglich beschrieben. Da musst du allerdings auch noch capture_output=True angeben, und dann auf der dem Rückgabeobjekt stdout auslesen:

o = subprocess.run(..., capture_output=True)
print(o.stdout)

Re: Mailversand per os.system()

Verfasst: Freitag 11. Januar 2019, 01:48
von __blackjack__
@Mesquita: Jain. Das geht natürlich auch in Python 3.5 aber da gibt's halt `run()`.

Re: Mailversand per os.system()

Verfasst: Freitag 11. Januar 2019, 11:02
von __deets__
Das sehr praktische capture_output leider wohl erst ab 3.7.

Re: Mailversand per os.system()

Verfasst: Freitag 11. Januar 2019, 18:40
von Mesquita
Sorry, ich denke ich wage mich zu weit vor. Meine Kenntnisse sind noch sehr dünn bzw. alt. In den Büchern steht zu subprocess noch garnichts, sind aber gerade mal 1 Monat alt. Wie erzeugt man ein Popen Objekt?

Thomas

Re: Mailversand per os.system()

Verfasst: Freitag 11. Januar 2019, 18:52
von __deets__
p = subprocess.Popen(....)

Oder eben subprocess.run, das noch ein paar nette Zusatzfunktionen bereitstellt wie zB check, mit dem man dann gleich einen Fehler bekommt, wenn der Prozess mit einem Fehlercode zurueckgekehrt ist.

Hast du dir die Dokumentation dazu mal angeschaut?

https://docs.python.org/3/library/subpr ... rocess.run

Re: Mailversand per os.system()

Verfasst: Dienstag 15. Januar 2019, 18:27
von Mesquita
Hallo deets,

die Doku habe ich mir angesehen, komme aber trotzdem damit nicht klar.

Code: Alles auswählen

p=subprocess.Popen(['mail', '-s', 'Betreff', '***@***.com'], stdin=PIPE)
print(p.stdout)
Das Ergebnis sieht folgendermaßen aus:

Code: Alles auswählen

NameError: name 'PIPE' is not defined
Mir fehlt einfach der Zugang, die Erfahrung. Nehme ich mir zu viel vor? Bitte verliert nicht die Geduld mit mir, ich kann auch nur unregelmäßig daran arbeiten. Das System muss im Ausland dann seine Dienste tun.

Thomas

Re: Mailversand per os.system()

Verfasst: Dienstag 15. Januar 2019, 20:18
von __blackjack__
@Mesquita: Es gibt eine Handvoll eingebaute Objekte deren Namen man einfach so verwenden kann. `PIPE` gehört nicht dazu, das ist im `subprocess`-Modul definiert. Also muss man das Modul importieren und die Konstante über das Modul referenzieren, wie Du das ja mit `Popen` auch machst, oder man muss es explizit mit ``from subprocess import PIPE`` importieren. Das gilt ganz generell.

Du solltest übrigens gar nicht erst mit einbuchstabigen Namen anfangen. `process` oder `mail_process` wären deutlich bessere Namen. Und nach dem Start des Prozesses, musst Du dann noch den Mailinhalt in das Dateiobjekt `mail_process.stdin` schreiben und danach schliessen, damit das ``mail``-Programm weiss, das die Daten komplett sind. Und dann mit der `wait()`-Methode auf das Ende des Prozesses warten.

Re: Mailversand per os.system()

Verfasst: Mittwoch 16. Januar 2019, 09:40
von Mesquita
Guten Morgen blackjack,

danke für die Hinweise. Ich arbeite an meinem kleinen Skript weiter und melde mich sobald ich wieder mal am "Ende" bin. Zuerst versuche ich den Hinweis "das Modul importieren und die Konstante über das Modul referenzieren, wie Du das ja mit `Popen` auch machst" zu beleuchten.

Thomas

Re: Mailversand per os.system()

Verfasst: Freitag 25. Januar 2019, 16:17
von Mesquita
Hallo blackjack,

ich kann einen Erfolg vermelden, die Mail geht mit gewünschtem Inhalt raus, allerdings nicht mit subprocess. Meine Kenntnisse sind nicht so umfassend, sodass ich die Hinweise nicht erfolgreich umsetzen konnte. Mein Ausweg ist die Verwendung von smtplib mit server.sendmail(). Liege ich bei server.sendmail() richtig, kann die Funktion keinen Betreff verarbeiten? Ist nur ein Schönheitsfehler.

Der nächste Punkt für mich ist das Handling einer Variable. Ich ermittle im Skript einen Laufzeitwert und möchte diesen beim nächsten Aufruf erneut überprüfen mit dem dann ermittelten Laufzeitwert. Dies bedeutet eine Zwischenspeicherung. Traditionell könnte man den Wert in eine Datei schreiben und ablegen. Allerdings möchte ich die Zugriffe auf den Datenträger reduzieren und dies im Arbeitsspeicher oä machen. Gibt es eine Möglichkeit den Inhalt einer Variable außerhalb des Scriptes zu erhalten ohne den Datenträger zu nutzen? Bei einem Neustart wäre dieser dann verloren, wäre auch kein Problem.

Thomas

Re: Mailversand per os.system()

Verfasst: Freitag 25. Januar 2019, 16:33
von __deets__
Hast du dein System sonst auch auf keine Schreibvorgaenge getunt? Wenn nicht kommt es nun darauf auch nicht an. Ansonsten bietet sich ein tmpfs an, zB fuer /tmp - da hast du dann eine RAM-Disk.

Re: Mailversand per os.system()

Verfasst: Freitag 25. Januar 2019, 16:52
von __blackjack__
@Mesquita: `sendmail()` versendet eine komplette Mail als Bytes. Wie sollte da ein Betreff bei der Funktion noch Sinn machen? Der steht ja schon in den Bytes. Und wenn er da nicht steht, machst Du etwas falsch. Wie kommen die Bytes denn bei Dir zustande und warum verwendest Du `sendmail()` und nicht `send_message()`? Das bedeutet doch das Du irgend etwas selbst machst, was diese Methode schon leistest, oder das Du etwas nicht machst, was Du besser machen solltest.