[Python-de] os.popen2()

Bertram Scharpf lists at bertram-scharpf.de
Sam Nov 20 02:48:32 CET 2004


Hallo,

Am Donnerstag, 18. Nov 2004, 18:14:24 +0100 schrieb Bertram Scharpf:
> ich möchte die Ausgabe einer Funktion durch ein externes
> Programm leiten, ungefähr so:
> 
>     old = 'Hallo, Pipe!\n'
>     i, o = os.popen2( 'sed s/^/:/')
>     i.write( old)
>     i.close()
>     del old
>     new = o.read()
> 
> Allerdings bleibt die Funktion `write' stehen, wenn der
> Puffer von 16384 Bytes voll ist, also mit:
> 
>     old = 'Hallo, Pipe!\n' * 1261
> 
> Wenn ich weniger als 16384 Bytes schreibe, bleibt der
> anschließende `read' stehen.
> 
> Wie geht der offiziell richtige Weg?

Ich habe mich zu folgender Lösung durchgerungen: Von einem
Programm ins andere und dann wieder ins vorherige
zurückzupipen ist nicht im Sinne des Erfinders. Pipes
sollten eine offene Kette sein, keine Schleife. Das war
wohl auch mit "Threading" gemeint.

Da ich ohnehin nur die Eingabe brauche, also quasi das
Gegenstück zu `popen', sage ich:


class Pipeto:
    def __init__( self, prgpath, *args):
        re, we = os.pipe()
        self.pid = os.fork()
        if not self.pid:
            os.dup2( re, sys.stdin.fileno())
            os.close( we)
            os.execvp( prgpath, [ prgpath] + list( args))
        else:
            os.close( re)
            self.oldstdout = sys.stdout
            sys.stdout = self.stdout = os.fdopen( we, 'w')

    def run( self):
        self.stdout.close()
        sys.stdout = self.oldstdout
        return os.waitpid( self.pid, 0)

    def __del__( self):
        self.run()

def postscript_ausgabe():
    p = Pipeto( *'mpage -4 -m60b -L60'.split())
    text_ausgabe()   # Funktion mit einigen `print's


Die Funktionen `popen2-4' scheint ja niemand in größerem
Stil zu nutzen. Das ist immer sehr verdächtig.

Danke für alle Anregungen.

Gruß
Bertram

-- 
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de