Seite 5 von 5

Re: Modul zum Nachinstallieren fehlender Pythonpakete

Verfasst: Samstag 14. Juli 2012, 10:35
von Dav1d

Code: Alles auswählen

        process = subprocess.Popen(commando, stdout=subprocess.PIPE)
        output = process.stdout.readlines()
        process.wait()
Dafür gibt es `process.communicate` (Die rote Warnung bei `process.stdout` hast du wohl übersehen), bzw. `check_call` oder `check_output`.

Zeile 4 bis 21 finde ich witzig, wieso sollte das Importieren beim zweiten Mal funktionieren?

Zeile 328, wieso fängst du `BaseException` ab und nicht `Exception`, denn `BaseException` fängt auch einen KeyboardInterrupt (aka Strg+C) ab?

Re: Modul zum Nachinstallieren fehlender Pythonpakete

Verfasst: Samstag 14. Juli 2012, 12:42
von Nobuddy
Hallo Dav1d, Danke für Deine Info! :wink:

In diesem Fall, funktioniert `process.communicate()` prima und vereinfacht hier auch den Code.

Code: Alles auswählen

outputerror = list()
def installation(paket):
    for line in install_command:
        commando = list(line)
        commando.append(paket.lstrip('-'))
        break

    counter = 0
    while counter != 4:
        counter += 1
        process = subprocess.Popen(commando)
        process.communicate()
        process.wait()
        install = process.returncode
        if install == 0:
            print ('Installation von %s war erfolgreich!\n' % paket)
            counter = 4
            return
        if counter < 4:
            print ('\nInstallationsfehler: %s, die Installation wird wiederholt!' % paket)
            time.sleep(5)
        elif counter == 4:
            outputerror.append('Es ist ein Fehler bei der Installation von aufgetreten, %s konnte nicht installiert werden!' % paket)
            return
Bei zwei anderen Funktionen, benötige ich für das Ausgabehandling 'process.stdout.readlines()'.

Zeile 4 bis 21 konnte ich noch kürzen, da 2 der Imports nicht mehr benötigt werden.
Warum ich zwei mal das Gleiche importiere. 'import pip' funktioniert nur, wenn das Paket 'pip' bzw. 'python-pip' auch installiert ist, was bei einer Python-Standardinstallation unter Debian / Ubuntu nicht der Fall ist. Daher habe ich das in eine 'try .. ecxept' gesteckt. Vielleicht gibt es da auch noch eine einfachere Lösung?

Bei Zeile 328, habe ich mir gedacht am Besten alle Fehler abzufangen. Ist das nicht von Vorteil?

Re: Modul zum Nachinstallieren fehlender Pythonpakete

Verfasst: Samstag 14. Juli 2012, 13:00
von snafu
Dav1d hat geschrieben:Dafür gibt es `process.communicate` (Die rote Warnung bei `process.stdout` hast du wohl übersehen), bzw. `check_call` oder `check_output`.
Er sagte irgendwo in diesem Thread mal, dass er die Doku nicht benutzt, weil er kein Englisch kann. Das erklärt wohl auch den Umstand, wieso er überhaupt solche Fragen stellt. ;)

Meiner bescheidenen Meinung nach sollten solche Leute ja besser die Finger vom Programmieren lassen, ebenso wie man besser kein Handwerker wird, wenn man zwei linke Hände hat. Aber da ich niemandem den Spaß verderben will (und an sich auch kein böser Mensch sein will), halte ich mich mal halbwegs zurück. :)

Re: Modul zum Nachinstallieren fehlender Pythonpakete

Verfasst: Samstag 14. Juli 2012, 13:49
von Dav1d
`communicate` gibt dir ein Tuple zurück welches STDOUT und STDERR-Ausgabe enthält, das ersetzt `process.stdout.readlines` und ist auch noch sicherer, des Weiteren brauchst du dann auch kein `process.wait` mehr (→ Dokumentation, wenn es stimmt was snafu gesagt hat, dass du kein Englisch kannst, dann nimm dir einen Übersetzer!)

4-21:

Code: Alles auswählen

import sys
import os
import time
import platform
import shlex
import subprocess
import imp
from subprocess import PIPE

try:
    import pip
except ImportError:
    pip = None
Dein `except BaseException` verhindert das Abbrechen deines Programms mit Strg+C, würde ein Programm das in meiner Konsole versuchen würde es ziemlich schnell fliegen (nach einem `kill` (-9)).

Re: Modul zum Nachinstallieren fehlender Pythonpakete

Verfasst: Samstag 14. Juli 2012, 16:15
von Nobuddy
@snafu, das stimmt so nicht!
Ich versuche mich wohl durch die englischen Dokus mit einem Translater zu lesen, leider ist es oft so mit der Übersetzung, daß der Sinn dabei allzu oft auf der Strecke bleibt und man sich selbst das zusammenreimen darf ...
Du kennst mich und meine Gründe nicht, warum Dir manches fraglich vorkommt.
Es gibt immer zwei Möglichkeiten, man lässt es oder man tut es ... :wink:

@Dav1d, das mit dem Englisch stimmt schon, Problem ist den Sinn bei solchen Übersetzungen richtig zu erkennen und das ist oft nicht so einfach. :wink:
Danke für Deine Info zu 'communicate' und dem Import-Vorschlag der besser und verständlicher aussieht.
Bei 'communicate' stört mich eins, daß ich die Ausgabe nicht an eine Variable übergeben kann und dies dann zu einem späteren Zeitpunkt abrufen kann. Wenn ich 'process.communicate()' aufrufe, erfolgt auch umgehend die Ausgabe und das ist vielleicht nicht immer erwünscht. Vielleicht gibt es auch dafür eine Lösung, die ist mir aber noch nicht bekannt, deshalb verwende ich noch bei zwei Funktionen eben `process.stdout.readlines`. Siehe Zeile 105 - 114 und 117 - 134 im aktuellen Link.

Hier die aktuelle modul_control.py: https://gist.github.com/3111763

Re: Modul zum Nachinstallieren fehlender Pythonpakete

Verfasst: Samstag 14. Juli 2012, 17:11
von Nobuddy
@Dav1d, vergiss was ich über die Notwendigkeit über `process.stdout.readlines` geschrieben habe.
Habe nochmals die Doku durchgearbeitet und an 'check_call, check_output' gedacht was Du vor zwei Posts mir angeraten hast. Mit 'check_output' konnte ich auch dieses Problem lösen und der Code ist dabei noch viel einfacher geworden! :)
Mit dem Translater, wäre ich darauf nicht gekommen, aber dank der selbsterklärenden Beispiele!
Siehe Zeile 105 - 111 und 116 - 128.

Aktuelle modul_control.py: https://gist.github.com/3112039

Re: Modul zum Nachinstallieren fehlender Pythonpakete

Verfasst: Samstag 14. Juli 2012, 23:03
von Dav1d
Diese Beispiel sollte dir zeigen wie `communicate` wirklich funktioniert:

Code: Alles auswählen

p = Popen([…], stderr=PIPE, stdout=PIPE)
stdout, stderr = p.communicate()
print stdout, stderr
print p.returncode

Re: Modul zum Nachinstallieren fehlender Pythonpakete

Verfasst: Sonntag 15. Juli 2012, 12:40
von Nobuddy
Danke für das Beispiel!
Habe es getestet, verhält sich so, wie in meinem Modul.

Da ja Python3 auch in der nächsten Ubuntu-Version Standard sein wird, habe ich noch ein paar kleine Änderungen vorgenommen, so daß es auf Python 2.7 und auch auf Python 3 läuft.

https://gist.github.com/3116344

Zukünftig werde ich mich mit Python3 beschäftigen.