[pyar] Ejecutando algo y enterándome qué pasa

Facundo Batista facundobatista en gmail.com
Mie Nov 21 14:06:22 ART 2012


2012/11/21 Facundo Batista <facundobatista en gmail.com>:

> Situación: tengo un string y debo ejecutarlo en la máquina (esto es
> bajo linux, para Launcherposta [0]).
>
> Ejemplo: "/usr/bin/gvim /home/facundo/fruta.txt"
>
> Quiero ejecutar ese string (del cual no tengo control) y si hay un
> error, indicárselo al usuario.
>
> Probé con
>
> a) subprocess.Popen(cmd, shell=True) -- el problema acá es que si el
> shell no encuentra el proceso, *yo no me entero* (no salta una
> excepción a nivel de Python)
>
> b) subprocess.Popen(cmd) -- acá no encuentra el comando, directamente;
> para que lo encuentre debería pasar cmd.split(), pero el tema es que
> hacer un split() a ciegas me puede convertir un comando que es
> "/bin/algo -t 3 foobar" en ["/bin/algo", "-t", "3", "foobar"] cuando
> realmente debería ser ["/bin/algo", "-t 3", "foobar"] (bah, creo).
>
> Puntos extras por tener el process id de lo que lancé, así lo logueo.

Gracias por los aportes a todos! Buscando un poco más, y siguiendo
links que me pasaron... terminé en la documentación de Python, :p

Puntualmente, acá:

  http://docs.python.org/2/library/subprocess.html#replacing-os-system

...que lo que hace es usar retcode = call(cmd, shell=True).

Yo no puedo usar .call() porque necesito NO esperar a que termine lo
que disparo, pero me dio la idea de leer el return code (exit status)
de shell, lo cual no es trivial, porque hay que esperar un ratito:

Al final, terminé haciendo esto, que funciona "lo suficientemente bien":

        try:
            p = subprocess.Popen(cmd, shell=True)
        except OSError, err:
            self.logger.error("Execution failed: %s", err)
            widgets.show_error_dialog("Execution failed: " + str(err))
        else:
            # wait for the shell to execute and give it time to finish by
            # error if it had a problem; note that this sleep time does
            # not affect at all the GUI interaction
            time.sleep(1)

            # the poll is needed for the returncode to be set
            p.poll()

            if p.returncode is None or p.returncode == 0:
                self.logger.info("Execution ok, pid=%d", p.pid)
            else:
                self.logger.error("Execution failed, child returned %r",
                                  p.returncode)
                widgets.show_error_dialog("Execution failed, child returned " +
                                          repr(p.returncode))


Lo único que me faltaría es "traducir" el exit status de bash a algo
más humano en los casos en que estén bien definidos.

Slds.

-- 
.    Facundo

Blog: http://www.taniquetil.com.ar/plog/
PyAr: http://www.python.org/ar/
Twitter: @facundobatista



More information about the pyar mailing list