Modul zum Nachinstallieren fehlender Pythonpakete
Leonidas wollte damit nicht ausdrücken, dass du das Modul in mehrere untereilen sollst, sondern dass der Code zu großen Teilen unterirdisch ist. Viele Dinge wurden ja schon genannt, auch in mindestens einem anderen Thread, die Hinweise scheinst du aber oft einfach zu ignorieren. Daher spar ich mir die Kommentare zu deinem Code.
Das Leben ist wie ein Tennisball.
@EyDu, ich ignoriere bestimmt nicht mit Absicht!
Benötige in manchen Dingen einfach mehr Zeit, bis mir das klar geworden ist.
Das hat wiederum nichts etwa mit mangelnder Intelligenz zu tun, sondern hat einen anderen Grund, den ich aber hier nicht weiter erörtern möchte. Sollte es Dich persönlich interessieren, schreibe mir eine Nachricht.
Wie dem Einen und Anderen von Euch bekannt ist, hapert es ja mit meinem Englisch, deshalb ist es oft auch schwierig für mich englische Texte richtig zu verstehen (trotz Translater).
Jetzt bin ich hier http://wiki.python-forum.de/PEP%208%20% ... setzung%29 auf die deutsche Übersetzung von PEP8 gestoßen. Diese habe ich schon des öfteren unter die Nase gerieben bekommen und werde diese Gelegenheit nutzen, mir PEP8 durchzulesen.
Benötige in manchen Dingen einfach mehr Zeit, bis mir das klar geworden ist.
Das hat wiederum nichts etwa mit mangelnder Intelligenz zu tun, sondern hat einen anderen Grund, den ich aber hier nicht weiter erörtern möchte. Sollte es Dich persönlich interessieren, schreibe mir eine Nachricht.
Wie dem Einen und Anderen von Euch bekannt ist, hapert es ja mit meinem Englisch, deshalb ist es oft auch schwierig für mich englische Texte richtig zu verstehen (trotz Translater).
Jetzt bin ich hier http://wiki.python-forum.de/PEP%208%20% ... setzung%29 auf die deutsche Übersetzung von PEP8 gestoßen. Diese habe ich schon des öfteren unter die Nase gerieben bekommen und werde diese Gelegenheit nutzen, mir PEP8 durchzulesen.
Hallo Leonidas,
habe Deinen letzten Post durchgearbeitet und entsprechende Änderungen vorgenommen, allerdings konnte ich Deinen Einwand gegen shlex noch nicht lösen. Ich poste hier mal den Code, in dem shlex enthalten ist.Ich habe dies versucht:Leider funktioniert dies so nicht. Was mache ich da falsch?
Ich poste hier mal den aktuellen Code, damit Ihr meine Fortschritte überprüfen könnt. http://www.python-forum.de/viewtopic.ph ... 1&start=45
habe Deinen letzten Post durchgearbeitet und entsprechende Änderungen vorgenommen, allerdings konnte ich Deinen Einwand gegen shlex noch nicht lösen. Ich poste hier mal den Code, in dem shlex enthalten ist.
Code: Alles auswählen
# Funktion zur Überprüfung
# ob ausgewähltes Paket schon installiert ist.
def installcheck(paket):
# Überprüfe ob Paket nicht installiert ist.
install_test = 'apt-cache policy %s' % paket
args = shlex.split(install_test)
process = subprocess.Popen(args, shell=False, stdout=subprocess.PIPE)
process.wait()
output = process.stdout.readlines()
global installinfo
if output:
for installinfo in output:
if 'Installiert:' in installinfo and not 'Installiert: (keine)' in installinfo:
print ('\nPaket %s ist installiert!\nÜberprüfen Sie bitte Ihr Modul auf Fehler!\n' % (paket, paket))
else:
return installinfo
else:
installinfo = False
Code: Alles auswählen
args = 'apt-cache policy %s' % paket
process = subprocess.Popen(args, shell=False, stdout=subprocess.PIPE)
Ich poste hier mal den aktuellen Code, damit Ihr meine Fortschritte überprüfen könnt. http://www.python-forum.de/viewtopic.ph ... 1&start=45
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Du solltest ``Popen`` auch keine Strings übergeben, sondern eine Liste, dann ist der Code auch gleich sauberer:
Kein ``shlex``, kein String-Formatting. Der Standardwert von ``shell`` ist sowieso ``False``, daher braucht man das *auch* nicht anzugeben.
Code: Alles auswählen
process = subprocess.Popen(['apt-cache', 'policy', paket], stdout=subprocess.PIPE)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
btw. es gibt auch das Python Modul apt, mit den man direkt in den Paketverwaltungsdaten wühlen kann.
Kurze such ergibt:
http://apt.alioth.debian.org/python-apt-doc/index.html
http://stackoverflow.com/questions/tagg ... sort=votes
Ich selbst habe es vor einiger Zeit auf einer anderen Baustelle genutzt:
https://github.com/jedie/autoaptitude/b ... agelist.py
Kurze such ergibt:
http://apt.alioth.debian.org/python-apt-doc/index.html
http://stackoverflow.com/questions/tagg ... sort=votes
Ich selbst habe es vor einiger Zeit auf einer anderen Baustelle genutzt:
https://github.com/jedie/autoaptitude/b ... agelist.py
Ja, dasfunktioniert, habe dies vorhin getestet.
Also keine Strings sondern eine Liste, bei obigem Beispiel kein Problem.
Beim installieren von Paketen, wo 'apt-get, aptitude und pip' ins Spiel kommen, muß ich da für jeden Befehl eine eigene subprocess-Zeile erstellen?
Den Installationsbefehl, erhalte ich aus dem Modul command(e_name), das zu installierende Paket von dem Modul noname(e_name).
Ich glaube im Moment stehe ich auf der Leitung ...
PS: Nachtrag, denke daß ich das gelöst bekomme!
Code: Alles auswählen
process = subprocess.Popen(['apt-cache', 'policy', paket], stdout=subprocess.PIPE)
Also keine Strings sondern eine Liste, bei obigem Beispiel kein Problem.
Beim installieren von Paketen, wo 'apt-get, aptitude und pip' ins Spiel kommen, muß ich da für jeden Befehl eine eigene subprocess-Zeile erstellen?
Den Installationsbefehl, erhalte ich aus dem Modul command(e_name), das zu installierende Paket von dem Modul noname(e_name).
Ich glaube im Moment stehe ich auf der Leitung ...
PS: Nachtrag, denke daß ich das gelöst bekomme!
Ok, dies z.B. gebe ich mit der globalen Variable 'install_command' weiter und mache daraus das dann in problemlos verarbeitet wird.
Das ist jetzt nichts Endgültiges!
Ich überlege, wie ich die Zeile mit 'commando = ...' optimieren kann, weil ja vielleicht nicht jeder Installationsbefehl wie hier 4 Wörter hat, wie mit 'pid install' z.B.?
Habe mal gesehen, daß man dies mit ''{} ...'.format(....)'' lösen kann, komme aber da nicht drauf. Ich weiß nur, daß 'len(install_command)' hier zur Lösung beiträgt ... ?
Weiß da jemand von Euch, was ich meine?
Code: Alles auswählen
APT_GET = 'sudo', 'apt-get', 'install', '-y'
Code: Alles auswählen
commando = install_command[0], install_command[1], install_command[2], install_command[3], paket.lstrip('-')
Code: Alles auswählen
process = subprocess.Popen(commando, stdout=subprocess.PIPE)
Das ist jetzt nichts Endgültiges!
Ich überlege, wie ich die Zeile mit 'commando = ...' optimieren kann, weil ja vielleicht nicht jeder Installationsbefehl wie hier 4 Wörter hat, wie mit 'pid install' z.B.?
Habe mal gesehen, daß man dies mit ''{} ...'.format(....)'' lösen kann, komme aber da nicht drauf. Ich weiß nur, daß 'len(install_command)' hier zur Lösung beiträgt ... ?
Weiß da jemand von Euch, was ich meine?
Code: Alles auswählen
>>> mylist = ["foo", "bar"]
>>> mylist + ["baz"]
['foo', 'bar', 'baz']
Dies funktioniert auch bei mir, das Andere hat es nicht!jens hat geschrieben:Wobei mylist.append("baz") normaler ist
Danke auch für die Links aus Deinem vorhergehenden Post, dafür muß ich mir allerdings etwas Zeit nehmen, da meine Englischkenntnisse ....
Hier mal eine ganz kurze Zusammenfassung:
Code: Alles auswählen
APT_GET = 'sudo', 'apt-get', 'install', '-y'
install_command = APT_GET
commando = list(install_command)
commando.append(paket.lstrip('-'))
print (commando)
Code: Alles auswählen
['sudo', 'apt-get', 'install', '-y', 'python-pip']
Code: Alles auswählen
def installation(paket):
commando = list(install_command)
commando.append(paket.lstrip('-'))
global outputerror
outputerror = ''
counter = 0
while outputerror == '':
counter += 1
try:
process = subprocess.Popen(commando, stdout=subprocess.PIPE)
process.wait()
output = process.stdout.readlines()
if output:
for line in output:
print (line)
time.sleep(5)
outputerror = False
return
except BaseException, e:
if counter < 4:
print ('\nInstallationsfehler: %s, die Installation wird wiederholt!' %e)
elif counter == 4:
print ('\nEs ist ein Fehler bei der Installation von aufgetreten, \n%s konnte nicht installiert werden!\n' % paket)
return
Bin auf dies gekommen, die Exception habe ich weggelassen, wird nicht benötigt.
Wenn etwas am Code nicht ok ist, würde ich mich über eine Info freuen!
Code: Alles auswählen
def installation(paket):
commando = list(install_command)
commando.append(paket.lstrip('-'))
global outputerror
outputerror = ''
counter = 0
while outputerror == '':
counter += 1
process = subprocess.Popen(commando, stdout=subprocess.PIPE)
process.wait()
output = process.stdout.readlines()
if output:
for line in output:
print (line)
if paket in line and 'wird eingerichtet ...' in line:
time.sleep(3)
outputerror = False
return
if counter < 4:
print ('\nInstallationsfehler: %s, die Installation wird wiederholt!' %e)
elif counter == 4:
print ('\nEs ist ein Fehler bei der Installation von aufgetreten, \n%s konnte nicht installiert werden!\n' % paket)
return
Das `global` ist kaputt.
the more they change the more they stay the same
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Du meinst wohl mylist += ["baz"] gemeint.snafu hat geschrieben:>>> mylist + ["baz"]
Das ist aber recht umständlich.Nobuddy hat geschrieben:Code: Alles auswählen
APT_GET = 'sudo', 'apt-get', 'install', '-y' install_command = APT_GET commando = list(install_command) commando.append(paket.lstrip('-')) print (commando)
Einfacher:
Code: Alles auswählen
APT_GET = ['sudo', 'apt-get', 'install', '-y']
commando = APT_GET[:] # Kopie der liste
commando.append(paket.lstrip('-'))
print (commando)
Ich habe es genau so gemeint, wie ich es geschrieben habe. Das "Addieren" zu einer Liste führt als Ergebnis zu einer neuen Liste mit dem hinzugefügten Element. Das ist quasi ein ``mylist = alist[:]; mylist.append(item)`` in einem Schritt und kann, wenn man die neue Liste danach eh wegschmeißen würde, IMHO durchaus sinnvoll sein.
Oder von mir aus auch:
Oder von mir aus auch:
Code: Alles auswählen
kommando = APT_GET + paket.lstrip('-')
@Dav1d, warum ist global kaputt?
@jens, den Code was ich zusammen gepostet habe, ist in unterschiedlichen Funktionen enthalten. Ich habe 3 Installationsbefehle zur Auswahl, daher übergebe ich als Erstes den ausgewählten Befehl an 'install_command'. 'APT_GET[:]' ist auch eine Alternative, aber 'list(APT_GET)' geht doch auch, oder soll man dies so nicht verwenden?
Was mich momentan beschäftigt, ist das 'process.wait()'.
Wird hier so lange gewartet, bis der Prozess positiv abgeschlossen ist?
Ich habe da beobachtet, daß wenn die Installation aus einem Grund fehlerhaft war, dies so lange geht bis die Installation erfolgreich war. Wenn das so ist (wäre), würden meine 2 ifś mit dem counter, nicht aktiv werden können.
Hoffe dabei kann mir jemand helfen!
@jens, den Code was ich zusammen gepostet habe, ist in unterschiedlichen Funktionen enthalten. Ich habe 3 Installationsbefehle zur Auswahl, daher übergebe ich als Erstes den ausgewählten Befehl an 'install_command'. 'APT_GET[:]' ist auch eine Alternative, aber 'list(APT_GET)' geht doch auch, oder soll man dies so nicht verwenden?
Was mich momentan beschäftigt, ist das 'process.wait()'.
Wird hier so lange gewartet, bis der Prozess positiv abgeschlossen ist?
Ich habe da beobachtet, daß wenn die Installation aus einem Grund fehlerhaft war, dies so lange geht bis die Installation erfolgreich war. Wenn das so ist (wäre), würden meine 2 ifś mit dem counter, nicht aktiv werden können.
Hoffe dabei kann mir jemand helfen!
@Nobuddy: ``global`` verwendet man nicht wenn man wartbare, verständliche Programme schreiben möchte. Ich bin mir ziemlich sicher dass das Thema schon mal angeschnitten wurde.
Ich würde ``list(obj)`` vorziehen weil das mit *jedem* iterierbaren Objekt funktioniert und nicht nur mit solchen, die die Slice-Syntax verstehen.
Das `process.wait()` ist an der falschen Stelle. Du kannst nicht auf das Ende des Prozesses warten und *danach* erst die Ausgabe auslesen. Wenn der andere Prozess mehr ausgibt als in den Puffer passt, den das Betriebssystem zwischen den beiden Prozessen verwaltet, dann hast Du eine Verklemmung. Dein Programm wartet auf das Ende des anderen Prozesses, und der andere Prozess wartet, dass dein Programm endlich die Ausgaben abnimmt, damit er zum Ende kommen kann. Beides passiert deswegen nie.
Ich würde ``list(obj)`` vorziehen weil das mit *jedem* iterierbaren Objekt funktioniert und nicht nur mit solchen, die die Slice-Syntax verstehen.
Das `process.wait()` ist an der falschen Stelle. Du kannst nicht auf das Ende des Prozesses warten und *danach* erst die Ausgabe auslesen. Wenn der andere Prozess mehr ausgibt als in den Puffer passt, den das Betriebssystem zwischen den beiden Prozessen verwaltet, dann hast Du eine Verklemmung. Dein Programm wartet auf das Ende des anderen Prozesses, und der andere Prozess wartet, dass dein Programm endlich die Ausgaben abnimmt, damit er zum Ende kommen kann. Beides passiert deswegen nie.
@BlackJack, Danke für Deine Info, habe dies geändert.
Das mit dem 'process.wait()' sollte jetzt an der richtigen Stelle stehen, oder?
Code: Alles auswählen
outputerror = list()
def installation(paket):
commando = list(install_command)
commando.append(paket.lstrip('-'))
counter = 0
while counter != 4:
counter += 1
process = subprocess.Popen(commando, stdout=subprocess.PIPE)
output = process.stdout.readlines()
process.wait()
if output:
for line in output:
print (line)
if paket in line and 'wird eingerichtet ...' in line:
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
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
du solltest den Zurückgabewert vom process überprüfen: http://docs.python.org/library/subproce ... returncode
etwa so:
Code: Alles auswählen
def installation(paket):
commando = list(install_command)
commando.append(paket.lstrip('-'))
counter = 0
while counter != 4:
counter += 1
process = subprocess.Popen(commando, stdout=subprocess.PIPE)
output = process.stdout.readlines()
process.wait()
install = process.returncode
if output:
for line in output:
print (line)
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
'global' konnte ich nun auch komplett durch 'list(obj)' ersetzen.
Poste hier mal den aktuellen Code von modul_control.py: https://gist.github.com/3109885
Vielleicht fallen Euch noch ein paar Leichen im Keller auf?
Poste hier mal den aktuellen Code von modul_control.py: https://gist.github.com/3109885
Vielleicht fallen Euch noch ein paar Leichen im Keller auf?