popen() auf win64

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
2d23d
User
Beiträge: 14
Registriert: Mittwoch 12. September 2007, 11:15

Mittwoch 12. September 2007, 11:59

Hallo zusammen!
Mein erster Post (hoffe, ich begehe nicht eine der Todsünden wie double-posts o.ä. :D ).

Ich bin hier auf folgendes Problem gestoßen:
Ich versuche, von WinXP64 aus auf einer linux-maschine via "find()" eine Ordnerliste zu lesen. dazu starte ich find() via plink mit "popen()" und parse den Output der Pipe. Soviel zum Hintergrund. Alles funktioniert wunderbar auf win32, allerdings hängt es auf win64 (wahrscheinlich in der while-schleife). Und das liegt an popen() (denke ich, denn wenn ich das command einfach so - ohne python - absetze, bekomme ich eine "normale" Antwort)
Habe es auch mit popen3 probiert, allerdings ohne Erfolg. Habe auch probiert, statt stdout stderr zu lesen, allerdings auch ohne Erfolg.
Der Prozess scheint auch irgendwie erfolgreich gestartet zu werden (kein fehler; er geht nicht in "except:"), kommt allerdings nie in der Ausgabe der Projekte an (print "["+str(i)+"] "+sProj), hängt wie gesagt wahrscheinlich in der while-Schleife.

Code: Alles auswählen

def GetExistingProjects(self):
        try:
            cmd = "plink.exe testuser@flame find //usr//discreet//clip//stonefs -type d "
            test = Popen(cmd, shell=True, stderr=PIPE, stdout=PIPE)
            #(child_stdin, child_stdout, child_stderr) = os.popen3(cmd)
            #proc = popen2.Popen3(cmd)

            while 1:
                line_out = test.stdout.readline()
                #line_out = child_stdout.readline()
                #line_out = proc.fromchild.readline()
                if (not line_out == ""):
                    sProject = str(line_out).rsplit("/",1)[1].strip()
                    self.lProjects.append(sProject)
                    
                if (not line_out): break

        except:
            print "something went wrong when trying to get existing projects on flame"
            raw_input('RETURN zum Beenden druecken')
            sys.exit()

        i=0
        for sProj in self.lProjects:
            print "["+str(i)+"] "+sProj
            i=i+1
        
        self.sProjectChoice = raw_input('Please select a projectnumber: ')
Zusammen mit dem Administrator haben wir verschiedene 32bit und 64bit Versionen von Python auf WinXP64 installiert, sowie pywin32 (bei Bedarf kann ich nochmal eine genaue Liste der probierten Installationen nachreichen).

Für Anhaltspunkte, woran der Hänger liegen könnte, wäre ich mehr als dankbar. Dank schonmal im Voraus

Philipp
BlackJack

Mittwoch 12. September 2007, 12:37

Als erstes würde ich `stderr` auf `STDOUT` statt auf `PIPE` umlenken. Dann kannst Du aus ``test.stdout`` lesen, ohne dass wegen nicht gelesener Ausgaben das Programm blockieren kann.

Deine Namensgebung entspricht nicht dem Style Guide. Funktionsnamen und Attribute werden für gewöhnlich in_kleinbuchstaben_mit_unterstrichen geschrieben. Ungarische Notation ist auch sehr unschön, insbesondere bei einer Sprache wie Python, die auf "Duck Typing" setzt, ist das erwähnen des Typs im Namen schlecht, weil bei einer Änderung des Typs entweder alle Namen geändert werden müssen, oder man falsche Informationen im Namen stecken hat.

Endlosschleifen sind mit ``while True:`` etwas deutlicher. So eine ``while``-Schleife ist hier aber gar nicht notwendig, weil Dateiobjekte iterierbar sind. Und zwar geben sie die Zeilen als Zeichenketten zurück. Der ``str``-Aufruf ist also auch nicht nötig. Damit würde aus der Schleife:

Code: Alles auswählen

            for line in test.stdout:
                project = line.rsplit('/', 1)[1].strip()
                self.projects.append(project)
Oder mit einem Generator-Ausdruck:

Code: Alles auswählen

            self.projects.extend(line.rsplit('/', 1)[1].strip()
                                 for line in test.stdout)

Die Ausgabe der Projekte lässt sich auch knapper formulieren:

Code: Alles auswählen

        for i, project in enumerate(self.projects):
            print '[%d] %s' % (i, project)
2d23d
User
Beiträge: 14
Registriert: Mittwoch 12. September 2007, 11:15

Mittwoch 12. September 2007, 14:45

Danke für die Hinweise, BlackJack.
Habe das so umgesetzt, und es funktioniert tatsächlich so besser (obwohl mir noch nicht so ganz einleuchtet, warum das auf win32 wunderbar durchging...)

ein zweites Problem gibt es jetzt zwar noch, wenn ich jetzt eine sehr langwierige Ausgabe (langer Kopiervorgang) parsen möchte (und sich dabei die GTK-GUI ständig updaten soll), aber das ist ein anderes Thema, das hier im Forum glaub ich schon angesprochen wurde.

Danke erstmal! (Vielleicht muss ich mich später nochmal melden :D )
Philipp
Antworten