Senden von Daten zwischen 2 Dateien, sys, stdin. pipe usw.

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
llinuxnoob
User
Beiträge: 4
Registriert: Montag 16. April 2018, 11:36

Guten Tag zusammen,

ich habe von Python nur rudimantaer Ahnung, mach das schon ne Weile aber wohl leider eher selten. Meine Idee ist das ein Programm Daten ein anderes mit Daten versorgt. Das klappt jetzt leider nicht so. Von dem gelesenem
konnte ich fuer mich nichts verwerte. Darum hier mein Versuch:

Code: Alles auswählen

python programm1.py | programm2.py

Code: Alles auswählen

oder halt 
python programm1.py < programm2.py
Also ueber pipe oder Kanal??? Ich habe das auf jeden Fall nicht ganz umrissen. Vielleicht kann mir das mal einer kurz erleutern.
Programm1:

Code: Alles auswählen

#!/usr/bin/python
import sys, time
import Adafruit_DHT

luftf1 = 22
luftf2 = 33
temp1 = 77
temp2 = 56

daten_liste = [luftf1, temp1, luftf2, temp2]

sys.stdout = daten_liste

Programm2:

Code: Alles auswählen

#!/usr/bin/python
import sys, time

x  =  raw_input

i = 0 

while i < len(x):
    print x[i]
    i = i + 1 
Tja, kann echt nicht so schwer sein aber ich raff es nicht. Hier schon mal Danke fuer eure Hilfe.

Tshau,

noobi
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Für die Kommunikation zwischen 2 Programmen nutzt man in der Kommandozeile Pipes. Eine Pipe hat einen Anfang und ein Ende. Dort docken quasi die Ausgabe von prog1 sowie am anderen Ende die Eingabe von prog2 an und dann können die Daten zwischen beiden fließen.

Auf Python-Ebene nutzt man das subprocess-Modul. Seit Python 3.5 gibt es dort die run()-Funktion, um ein Programm auszuführen. Die Kommunikation zwischen 2 Python-Programmen passiert aber normalerweise über Module, d.h. anstatt zweimal Python zu starten, importiert stattdessen prog1 einfach prog2 und greift über dessen Schnittstelle auf die gewünschte Ausgabe zu. Das hängt aber auch davon ab, ob das andere Programm eine passende Schnittstelle, d.h. einen entsprechenden Funktionsaufruf, für die Ausgabe anbietet.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@llinuxnoob: warum willst Du zwei getrennte Programme haben?

Mit `<` wird die Datei ans Programm als Standardeingabe umgeleitet, und `|` ist das Pipe-Zeichen, das erwartet aber zwei Programme, so dass das bei Dir wahrscheinlich so aussehen müßte:
[codebox=bash file=Unbenannt.bsh]python programm1.py | python programm2.py[/code]

Bei den Programmen an sich fehlen Dir noch entscheidende Grundlagen, was Variablen sind, wie Zuweisungen und Funktionsaufrufe gemacht werden, wie man etwas ausgibt, oder einliest und letztlich was for-Schleifen sind. Du wirst nicht drum herum kommen, wirklich Python zu lernen; dann ist man auch weniger frustriert.
llinuxnoob
User
Beiträge: 4
Registriert: Montag 16. April 2018, 11:36

Schade das ich von euren Antworten nichts direkt umsetzen kann. Dann muss ich wohl weiter mit Google kaempfen oder ich poste mal bei Stackoverflow. Das frustrierende am Programmieren ist das es regelmaessige Uebung braucht, diese Regelmaessigkeit ist aber von mir nicht zu leisten. :(
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Du kannst auf die Weise nur bytes übertragen und keine Objekte. Das heisst du musst in einem Program die Daten erstmal serialisieren und in dem anderen parsen.

Das musst du erstmal implementieren, was mit ziemlich viel Aufwand verbunden ist und ist auch aus Performance Aspekten eher weniger gut. Deswegen rät dir bisher jeder Post mehr oder weniger ganz stark davon ab dies zu tun. Selbst wenn man professionell programmiert hält man von sowas weit Abstand. Du sagst von dir selbst dass du nicht soviel Zeit investieren kannst/willst, da macht es wahrscheinlich nicht soviel Sinn wenn du diesen Ansatz weiterverfolgst.

Wenn du bereit bist einen Schritt zurückzugehen und zu erklären was du eigentlich vorhast, kann man da vielleicht einen einfacheren Ansatz finden, der dir erlaubt dich mehr auf dein eigentlich Ziel zu konzentrieren als darauf auf sehr komplizierte Art und Weise irgendwie Daten hin und herzuschieben.
llinuxnoob
User
Beiträge: 4
Registriert: Montag 16. April 2018, 11:36

Hi DasIch, das ist natuerlich eine interessante Informatione. Youtube hat mich gelehrt das man seine Programme moeglichst speziell halten soll, war so ein CCC Video. Was ich also Umsetzen will ist ein Programm das nur Sensordaten ausliesst und ein zweites Programm was darauf reagiert, sprich einen Motor ansteuert. Das ganze soll auf Luftfeuchtigkeit und Temperaur reagieren. Was ich halt bauen koennte waere das Programm1 in eine Datei schreibt und Programm2 daraus ausliest, aber der Ansatz mit der Pipe erschien mir halt sinnvoller und ich dachte auch einfacher.

Ist es denn wirklich so schwierig ueber die bash zwei Python Skripte zu verbinden???
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Welchen Vorteil sollte es denn haben, zwei Programme zu schreiben, statt nur eins?

Du hast recht, dass Pipes um einiges einfacher sind, als dass Programme über Dateien kommunizieren. Aber noch einfacher ist es, direkt in einem Programm Funktionen aufzurufen.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Ist es denn wirklich so schwierig ueber die bash zwei Python Skripte zu verbinden???
Nein, aber es ist relativ sinnlos, weil viel zu umständlich. Der bereits mehrfach genannte import-Mechanismus von Python ist um Längen einfacher und flexibler.

Gruß, noisefloor
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Du kannst, wie bereits geschrieben, 2 Programme mit einer Pipe verbinden. Das Programm, das quasi senden soll, schreibt dazu seine Ausgaben mit print(). Das Programm, dass empfangen soll, durchläuft zeilenweise den Inhalt von STDIN:

Code: Alles auswählen

# prog1.py
print('Hallo Welt!')
print('Dies ist ein Test')
print('Letzte Zeile')

Code: Alles auswählen

# prog2.py
import sys

# Ausgabe vom verbundenen Programm mit nummerierten Zeilen
for no, line in enumerate(sys.stdin, 1):
    print(no, line, end='')
Und die beiden kannst du jetzt "zusammenschalten":
[codebox=bash file=Unbenannt.bsh]python prog1.py | python prog2.py[/code]

Dass dies langsam, kompliziert und fehleranfällig werden kann, wenn man es in größerem Umfang anwendet, wurde ja bereits erwähnt. Du kannst es gern zum Ausprobieren nehmen und damit herum spielen, aber für den regelmäßigen Gebrauch solltest du dir echt besser Module und API-Aufrufe anschauen. Sonst verrennst du dich da in was. Bedenke: Die Leute, die dir hier Tipps geben, programmieren nicht erst seit gestern und haben entsprechende Erfahrungen. ;)
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

llinuxnoob hat geschrieben:Youtube hat mich gelehrt das man seine Programme moeglichst speziell halten soll, war so ein CCC Video.
Grundsätzlich nicht verkehrt aber die Frage ist natürlich was "speziell" heisst. Ein ähnliches Problem taucht im Kontext von Microservices auf wo sich die Frage stellt wie groß so ein Microservice eigentlich sein sollte.

Die Frage lässt sich grundsätzlich nicht so einfach beantworten. In der Praxis ist es allerdings so dass so ein Design eine Gewisse Grundkomplexität mit sich bringt. Sofern deine Anwendung selbst also nicht ein Gewisses Minimum an Komplexität überschreitet, ist es Kontraproduktiv es irgendwie aufzuteilen.

Wenn du hunderte oder tausende Entwickler hast macht sowas Sinn weil so viele Leute nicht alle im selben Topf rühren können, wenn du ein kleineres Unternehmen bist oder an einem Hobbyprojekt arbeitest lohnt sich sowas eher nicht.
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

llinuxnoob hat geschrieben:Was ich also Umsetzen will ist ein Programm das nur Sensordaten ausliesst und ein zweites Programm was darauf reagiert, sprich einen Motor ansteuert. Das ganze soll auf Luftfeuchtigkeit und Temperaur reagieren.
Schau vielleicht mal in diesen Thread hier nebenan: viewtopic.php?f=31&t=42581

Darin will ein anderer Anfänger ein ganz ähnliches Projekt starten nämlich Daten auslesen (Drehregler) und anschließend reagieren (Lautstärke vom Lautsprecher regeln), aber scheitert an einer Idee, wie die beiden "Programme" miteinander Daten austauschen sollen.
Er hat noch die zusätzliche Herausforderung, dass er das ganze auch noch grafisch darstellen will, das hattest du nicht erwähnt.

Ganz gibt es hier noch zu wenige Angaben, was du konkret erreichen willst, und viel zu viele konkrete Ideen, wie es umgesetzt werden muss. Bitte löse dich mal von den technischen Details, gerade wenn du Anfänger bist, und beschreibe dein Ziel, nicht einzelne Schritte auf dem Weg.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
llinuxnoob
User
Beiträge: 4
Registriert: Montag 16. April 2018, 11:36

Ok ok, danke fuer den ausfuehrlichen Zuspruch. :? Also ich gebe das jetzt hiermit auf. Immerhin habe ich ein paar Interessante Links zum Thema Pipe gelesen. Dass das ganze ein Overkill sein koennte ist mir jetzte klar geworden. Wollte es halt besonders elegant anstellen. Das ganze soll auf jeden Fall ohne GUI auskommen, ganz vielleicht kommt noch ein 2,5 Zoll Display dazu. Also noch mal Danke das ihr euch die Zeit genommen habt es mir erklaeren. Ich habe Heute schon WE und wuensche euch so gutes Wetter wie bei mir (naehe Muenster).

Liebe Gruesse,

noobi
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

llinuxnoob hat geschrieben:Meine Idee ist das ein Programm Daten ein anderes mit Daten versorgt. Das klappt jetzt leider nicht so.
...
Also ueber pipe oder Kanal??? Ich habe das auf jeden Fall nicht ganz umrissen. Vielleicht kann mir das mal einer kurz erleutern.
Programm1:

Code: Alles auswählen

#!/usr/bin/python
import sys, time
import Adafruit_DHT

luftf1 = 22
luftf2 = 33
temp1 = 77
temp2 = 56

daten_liste = [luftf1, temp1, luftf2, temp2]

sys.stdout = daten_liste

Programm2:

Code: Alles auswählen

#!/usr/bin/python
import sys, time

x  =  raw_input

i = 0 

while i < len(x):
    print x[i]
    i = i + 1 
Hallo noobi,

probiers mal hiermit:

Code: Alles auswählen

#!/usr/bin/python
import sys, time
import Adafruit_DHT

def daten_erheben():
    luftf1 = 22
    luftf2 = 33
    temp1 = 77
    temp2 = 56
    daten = [luftf1, temp1, luftf2, temp2]
    return daten

def daten_auswerten(daten):
    for datum in daten:
        print datum

daten_auswerten(daten_erheben())
Falls das Programm dann in 2-3 Wochen zu umfangreich wird, kannst du daten_auswerten in eine eigene Datei auslagen und ebenfalls per import dazu holen.

Schönes Wochenende! :mrgreen:
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Antworten