Mailversand per os.system()

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Benutzeravatar
Mesquita
User
Beiträge: 15
Registriert: Montag 7. Januar 2019, 15:22

Dienstag 8. Januar 2019, 18:58

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

Dienstag 8. Januar 2019, 19:35

`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)
“I am Dyslexic of Borg, Your Ass will be Laminated” -- unknown
Benutzeravatar
Mesquita
User
Beiträge: 15
Registriert: Montag 7. Januar 2019, 15:22

Mittwoch 9. Januar 2019, 16:08

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

Mittwoch 9. Januar 2019, 16:23

Ja, das ist eine alte Python-Version. Du solltest tatsaechlich auf Python3 umsteigen.
Benutzeravatar
__blackjack__
User
Beiträge: 3365
Registriert: Samstag 2. Juni 2018, 10:21

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.
“I am Dyslexic of Borg, Your Ass will be Laminated” -- unknown
Benutzeravatar
Mesquita
User
Beiträge: 15
Registriert: Montag 7. Januar 2019, 15:22

Mittwoch 9. Januar 2019, 17:07

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

Mittwoch 9. Januar 2019, 17:10

Hallo blackjack,

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

Thomas
Sirius3
User
Beiträge: 9902
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 9. Januar 2019, 17:53

Schau mal genau, was __blackjack__ geschrieben hat. Außerdem sollte input noch binär sein, oder ein encoding= angegeben werden.
Benutzeravatar
Mesquita
User
Beiträge: 15
Registriert: Montag 7. Januar 2019, 15:22

Donnerstag 10. Januar 2019, 18:39

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

Freitag 11. Januar 2019, 01:40

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

Freitag 11. Januar 2019, 01:48

@Mesquita: Jain. Das geht natürlich auch in Python 3.5 aber da gibt's halt `run()`.
“I am Dyslexic of Borg, Your Ass will be Laminated” -- unknown
__deets__
User
Beiträge: 5621
Registriert: Mittwoch 14. Oktober 2015, 14:29

Freitag 11. Januar 2019, 11:02

Das sehr praktische capture_output leider wohl erst ab 3.7.
Benutzeravatar
Mesquita
User
Beiträge: 15
Registriert: Montag 7. Januar 2019, 15:22

Freitag 11. Januar 2019, 18:40

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

Freitag 11. Januar 2019, 18:52

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

Dienstag 15. Januar 2019, 18:27

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
Antworten