Seite 1 von 1

Aufruf eines Python Scripts innerhalb der bash

Verfasst: Samstag 19. Dezember 2020, 00:48
von jba
Ich habe eine ziemlich spezielle Frage und bin mir nicht ganz sicher, ob das das richtige Forum ist. Falls nicht, könnt ihr mir ja Tipps geben, wo ich damit besser aufgehoben bin.

Mein System läuft unter debian wheezy. Ich habe aus den Sourcen Python 3.6 installiert. Leider kann ich nicht auf eine neuere Version upgraden.

Ich habe eine Python Script geschrieben, dass in einer Dauerschleife läuft und dabei immer mal wieder Daten über print auf der Konsole aus. Dieses Python Script wird nun in einem Shell-Script (bash) aufgerufen und dabei direkt in den Hintergrund geschoben (mit &). Das Ganze sieht dann etwa so aus (der ping Befehl ist nur ein Beispiel dafür, dass mein Shell Script noch selber etwas tut und eigene Ausgaben hat):

Code: Alles auswählen

#!\bin\bash

Python-Script &

ping www.heise.de

Wenn ich das Shell-Script direkt auf der Konsole laufen lasse, tut es genau, was es soll. ich sehe den Output des Python-Scripts und des bash-Scripts (ping) gemischt.

Wenn ich die Ausgabe des Shell Scripts aber umleite, indem ich es mit

Code: Alles auswählen

> ./Shell-Script  >> output.log 2>&1
aufrufe, sehe ich die Ausgabe des Python-Scripts nicht mehr. Das Python-Script arbeitet aber noch im Hintergrund und macht genau, was es soll. Nur die Ausgabe fehlt.

Ich hab dazu jetzt schon länger gegoogelt aber nichts passendes gefunden.

Gruß,

Jürgen

Re: Aufruf eines Python Scripts innerhalb der bash

Verfasst: Samstag 19. Dezember 2020, 12:24
von noisefloor
Hallo,

das ganze ist konzeptionell ein bisschen komisch. Wenn das Programm im Hintergrund läuft, ist es eher ungewöhnlich das in die Konsole (bzw. stdout) geschrieben wird. Wenn man das will, lässt man das Programm eher im Vordergrund. Wenn das Programm im Hintergrund läuft und irgendwelche Daten zur Verfügung stellen soll, dann eigentlich eher über eine Logdatei oder eine Named Pipe oder eine Datenbank oder eine Socket oder ...

Bzgl. der eigentlichen Fragen: `&` führt den Befehl in einer Subshell aus. Kann also sein (weiß ich aber nicht 100%), dass stdout der Subshell nicht stdout der Hauptshell ist, in dem dein Bash-Skript läuft.

Gruß, noisefloor

Re: Aufruf eines Python Scripts innerhalb der bash

Verfasst: Samstag 19. Dezember 2020, 14:23
von Sirius3
Du leitest doch die Ausgabe nach output.log um. Warum soll dann noch eine Ausgabe erfolgen?

Du meinst, dass beim Umleiten in eine Datei der Ausgabebuffer so groß ist, dass die Ausgabe nicht mehr Zeile für Zeile parallel erfolgt?

Code: Alles auswählen

stdbuf -oL -eL pythonscript &
stdbuf -oL -eL ping heise.de
@noisefloor: es gibt nur eine Ausgabe stdout, die ist die selbe für Programme im Vorder- und Hintergrund, solange man nicht stdout irgendwohin umleitet.

Re: Aufruf eines Python Scripts innerhalb der bash

Verfasst: Samstag 19. Dezember 2020, 17:32
von jba
Danke für die Unterstützung! Inzwischen bin ich auch selber drauf gekommen. Sirius3 lag richtig. Das Problem ist der große Buffer, den Python verwendet, wenn man das Programm im Hintergrund laufen lässt und die Ausgabe umleitet.

Der Vorschlag von Sirius3 macht wahrscheinlich letztendlich das gleiche wie meine Lösung. Vor dem Aufruf des Python-Scripts setze ich eine Umgebungsvariable, die den Buffer auf null setzt:

Code: Alles auswählen

export PYTHONUNBUFFERED=1
Damit kommt in der Ausgabedatei alles so an, als wenn ich das Script direkt auf der Konsole starte.


@noisefloor: Ja, das mag ungewöhnlich sein, aber in dem Fall ist es so gewollt und macht auch Sinn. Ist so ähnlich wie z.B. /var/log/messages, wo auch verschiedene Programme gleichzeitig in die gleiche log-Datei schreiben. Auch hier sollen die Ausgaben des Python-Scripts, das im Hintergrund läuft, chronologisch im log-File des Shell-Scripts auftauschen.

jba

Re: Aufruf eines Python Scripts innerhalb der bash

Verfasst: Samstag 19. Dezember 2020, 20:04
von Thants
Nur noch so als Ergänzung, eine weitere Möglichkeit wäre sys.stdout.flush() aufzurufen, nachdem du deine Ausgabe gemacht hast. Damit werden die momentan gepufferten Daten rausgeschrieben.