staging.inyokaproject.org

Wie Programme unter Python 3 aufrufen?

Status: Ungelöst | Ubuntu-Version: Ubuntu 20.04 (Focal Fossa)
Antworten |

marlem

Avatar von marlem

Anmeldungsdatum:
12. Juli 2016

Beiträge: 139

so, wie versprochen hier die Lösung:

1
2
3
4
5
6
7
8
   elif varkommando == "textverarbeitung ubuntu":
        process = subprocess.Popen(["/usr/lib/libreoffice/program/soffice", "--writer", *sys.argv[1:]],
                                   stdin = subprocess.PIPE, stdout = subprocess.PIPE)
        process.wait()
    elif varkommando == "tabellenkalkulation ubuntu":
        process = subprocess.Popen(["/usr/lib/libreoffice/program/soffice", "--calc", *sys.argv[1:]],
                                   stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        process.wait()

Vielen Dank für Eure Hilfe!

Moderiert von rklm:

Der Übersichtlichkeit halber habe ich das Thema jetzt von diesem abgetrennt. Mittlerweile geht es ja darum, wie man so einen Aufruf in Python 3 technisch korrekt bewerkstelligt. Bitte bleibt bei einem Thema pro Thema! (siehe auch Richtig fragen)

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4735

Die Umleitung von stdin und stdout ist unsinnig bis fehlerhaft. Das gestartete Programm erwartet keine Eingaben auf stdin und das Python-Programm schreibt da auch nichts rein, also macht diese Umleitung keinen Sinn. Und die Umleitung von stdout des externen Programms in das Python-Programm ist fehlerhaft solange man die dann nicht auch tatsächlich ausliest. Denn falls das externe Programm etwas auf stdout schreibt kann der Ausgabepuffer volllaufen und dann hängt das Programm solange bis die Ausgabe auch gelesen wird. Was nicht passiert, womit das ganze bis in alle Ewigkeit hängen bleibt.

Wenn man einfach nur das externe Programm laufen lassen und warten will bis es fertig durchgelaufen ist, ist subprocess.run() das Mittel der Wahl.

Wobei im Falle von LibreOffice vielleicht noch anzumerken wäre, dass sich der Aufruf anders verhält, je nachdem ob bereits ein LibreOffice-Fenster/Prozess besteht oder nicht. Denn nur der erste Aufruf, wenn kein Fenster besteht, blockiert tatsächlich so lange bis das Fenster, beziehungsweise alle Fenster wieder geschlossen wurden. Ein Aufruf bei bereits mindestens einem bestehenden Fenster startet nur kurz einen Prozess der den bereits laufenden Prozess informiert, dass noch ein weiteres Fenster geöffnet werden soll und sich dann gleich beendet.

marlem

(Themenstarter)
Avatar von marlem

Anmeldungsdatum:
12. Juli 2016

Beiträge: 139

Ich bin Python-Anfänger und habe den Code durch Googeln herausgefunden. Ich weiß auch nicht ob das hier:

1
*sys.argv[1:]

Sinn macht. Schreib mal bitte den Code so wie Du denkst, dass es richtig ist und ich teste dann ob es bei mir funktioniert.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4735

Wenn Du nicht weisst ob *sys.argv[1:] Sinn macht, dann macht es das wahrscheinlich nicht, aber Du musst Du ja schon irgendwo selbst wissen.

Im simpelsten Falle einfach nur:

1
2
3
4
5
6
7
        ...
    elif command == "textverarbeitung ubuntu":
        subprocess.run(["libreoffice", "--writer"])
    elif command == "tabellenkalkulation ubuntu":
        subprocess.run(["libreoffice", "--calc"])
    else:
        ...

Das startet die Prozesse ohne sich um den Rückgabecode zu kümmern. Also quasi äquivalent zu einem Bash-Skript das Programme ausführt ohne sich um $? zu kümmern:

1
2
3
4
5
6
7
        ...
    elif [[ $command = "textverarbeitung ubuntu" ]]; then
        libreoffice --writer
    elif [[ $command = "tabellenkalkulation ubuntu" ]]; then
        libreoffice --calc
    else
        ...

Falls man eine Ausnahme generiert haben möchte wenn der Rückgabecode ≠0 war, kann man noch check=True bei den Aufrufen mitgeben und ein try/except um die Aufrufe legen, die den subprocess.CalledProcessError behandeln.

Für den Fall das alle if/elif-Zweige dem gleichen Muster folgen, oder zumindest ein grösserer Anteil davon der die Texte von command dem Aufruf eines externen Programms zuordnet, könnte man das auch mit einem Wörterbuch statt der if/elif lösen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
COMMAND_TO_ARGUMENTS = {
    "textverarbeitung ubuntu": ["libreoffice", "--writer"],
    "tabellenkalkulation ubuntu": ["libreoffice", "--calc"],
}

    ...
    try:
        subprocess.run(COMMAND_TO_ARGUMENTS[command])
    except KeyError:
        ...
Antworten |