Mailversand per os.system()

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Benutzeravatar
__blackjack__
User
Beiträge: 13006
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
Mesquita
User
Beiträge: 15
Registriert: Montag 7. Januar 2019, 15:22

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
Benutzeravatar
Mesquita
User
Beiträge: 15
Registriert: Montag 7. Januar 2019, 15:22

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
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Benutzeravatar
__blackjack__
User
Beiträge: 13006
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
Mesquita
User
Beiträge: 15
Registriert: Montag 7. Januar 2019, 15:22

Hallo deets,

der Entwickler hat dieses spezielle System "hoffentlich" getunt, so wird es zumindest behauptet. Die Idee mit der RAM-Disk ist wirklich gut. Jetzt ist nur die Frage wie richte ich dies unter Debian ein und greife dann im Skript darauf zu?

Im März wird das System ca. 3000km entfernt installiert und muss dann ohne physischen Zugriff seine Dienste tun. Einen externen Zugriff per ssh wird durch ein Fremdsystem in der Kette nicht möglich sein, ich keine Routen auf allen Systemen eintragen. Die Gespräche laufen dazu noch.

Thomas
Benutzeravatar
__blackjack__
User
Beiträge: 13006
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Mesquita: Ich würde einfach `/run/user/{$uid}` verwenden und darauf bauen, dass das auf einem `tmpfs` liegt. Worauf man dort achten sollte, ist die Zeit der Datei mindestens alle 6 Stunden mal zu aktualisieren, weil im XDG-basedir-Standard steht, dass dort periodisch alte Dateien entfernt werden dürfen, mit diesem Zeitrahmen. Das Verzeichnis sollte auch in der Umgebungsvariable `$XDG_RUNTIME_DIR` stehen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Da Linux ohne /tmp und so weiter nicht wirklich kann, wuerde ich halt einfach mal pruefen, OB der Entwickler eben so getunt hat. Das kannst du zb mit mount feststellen. Da muss dann irgendwo tmpfs auftauchen. Und in dem Moment kannst du auch einfach eine Datei darin anlegen. Wenn das nicht auftaucht, hat er seine Arbeit nicht gemacht, und sollte das nachholen.

Und du koenntest natuerlich dein Skript auch einfach dauerhaft laufen lassen, mit einer sleep-Schleife. Wenn es eh nicht auf nicht-volatile Informationen ankommt.
nezzcarth
User
Beiträge: 1632
Registriert: Samstag 16. April 2011, 12:47

Falls es /tmp nicht gibt, kannst du mal schauen, ob vielleicht /dev/shm existiert und ausnahmsweise das nehmen (das ist üblicherweise auch ein tempfs). Und wenn du dein Skript per Systemd Unit startest, ist es übrigens möglich, ein Privates /tmp anzulegen. Da kümmert sich dann systemd drum und du kannst einfach nach /tmp schreiben und wenn der Service beendet ist, wird das automatisch weggeräumt. https://www.freedesktop.org/software/sy ... rivateTmp=
Benutzeravatar
Mesquita
User
Beiträge: 15
Registriert: Montag 7. Januar 2019, 15:22

Danke für die vielen schnellen Feedbacks. Interessant finde ich die Idee der sleep Schleife von deets. Dies werde ich einmal aufgreifen und dann die nächste Erweiterung planen. Nach den tempfs schaue ich auch. Melde mich dann wieder.

Danke.

Thomas
Benutzeravatar
Mesquita
User
Beiträge: 15
Registriert: Montag 7. Januar 2019, 15:22

Hallo Helfer...

ich habe das Script mit Eurer Unterstützung entwickeln können und dabei viel gelernt. Besonders eingeprägt hat sich, dass ich noch viel lernen muss. Ich bin aber mit dem ersten Ergebnis sehr zufrieden. Dank der letzten Hinweise habe ich die time.sleep() Funktion eingesetz und damit das gewünschte Ergebnis erreicht. Das System läuft jetzt testhalber im Büro und fliegt im März zum Bestimmungsort.

Ich möchte mich nochmal recht herzlich bei Euch bedanken für die Bemühungen, Unterstüzungen und Hinweise, wie aber auch für Euer Verständnis über meine Unkenntnis.

Auf alle Fälle habe ich das Interesse an Python weiter gewonnen und werde sicherlich mit dem nächsten Projekt hier präsent sein. Bis bald.

Thomas
Antworten