[Python] esecuzione subprocess, scrittura stdin e lettura stdout

Valentino Volonghi dialtone a gmail.com
Ven 22 Feb 2008 13:48:43 CET


On Thu, Feb 21, 2008 at 11:42 AM, Daniele Varrazzo <piro a develer.com> wrote:
>  Credo che l'implementazione pił diffusa in python sia pexpect
>  (http://www.noah.org/wiki/Pexpect).

Direi Twisted invece io :).

def spawnProcess(processProtocol, executable, args=(), env={},
                 path=None, uid=None, gid=None, usePTY=0,
                 packages=()):

    env = env.copy()

    pythonpath = []
    for pkg in packages:
        p = os.path.split(imp.find_module(pkg)[1])[0]
        if p.startswith(os.path.join(sys.prefix, 'lib')):
            continue
        pythonpath.append(p)
    pythonpath = list(sets.Set(pythonpath))
    pythonpath.extend(env.get('PYTHONPATH', '').split(os.pathsep))
    env['PYTHONPATH'] = os.pathsep.join(pythonpath)

    return reactor.spawnProcess(processProtocol, executable, args,
                                env, path, uid, gid, usePTY)


def deferToProcess(prot, *args):
    args = (sys.executable,) + args

    proc = spawnProcess(
            prot, tuple(args), packages=('adroll',))

    def _eb(reason):
        reason.trap(error.ProcessDone)
        log.msg("FATAL: There was an error running the %s: %s" %
(prot.__class__.__name__, reason,))
    def _cb(data):
        log.msg("Successfully processed: %s bytes" % (len(data),))
        return data
    prot.d.addErrback(_eb)
    prot.d.addCallback(_cb)
    return prot.d

class BaseProtocol(protocol.ProcessProtocol):
    def __init__(self):
        self.d = defer.Deferred()
        self._buffer = []

    def connectionMade(self):
        log.msg("Started %s" % (self.__class__.__name__,))
        self.transport.write("PARTENZAAAAA")

    def outReceived(self, data):
        # qua gestisco l'output del processo come voglio
        # eventualmente chiamo anche self.transport.write() per dirgli qualcosa
        # volendo posso passare questo data al metodo dataReceived di
un qualsiasi
        # protocollo implementato da Twisted e parlero` col figlio
come prestabilito
        # dal protocollo, posto di settare anche il transport del
protocollo a quello di
        # questa istanza.
        self._buffer.append(data)

    def processEnded(self, status):
        log.msg("%s" % (status.value,))
        if status.check(error.ProcessDone):
            self.d.callback(''.join(self._buffer))
            return
        self.d.errback(status)

    def errReceived(self, data):
        log.msg("Received stderr from subprocess: %s" % (data,))

def _cb(arg):
    # questa si chiama solo alla fine di tutto, se il processo dura 20
ore questa
    # viene chiamata tra 20 ore.
    print "finito con", arg
    reactor.stop()

prot = BaseProtocol()
defertToProcess(prot, '/un/executable/qua', 'e', 'gli',
'argomenti').addCallback(_cb)

reactor.run()

Questo giusto per fare un esempio :).



-- 
Valentino Volonghi aka Dialtone
Now running MacOS X 10.5
Home Page: http://www.twisted.it


More information about the Python mailing list