Página 1 de 1

Scripts de Bash desde Python

Publicado: Jue, 17 Jul 2014, 18:19
por newbie
Creo que este es el mejor sitio para solucionar mi problema.
Los scripts de Bash son notablemente útiles en el uso del sistema GNU/Linux y deseo saber cómo se pueden ejecutar dentro de las líneas de código de un programa escrito en Python.
Agradezco la ayuda por adelantado. ;)

Re: Scripts de Bash desde Python

Publicado: Lun, 21 Jul 2014, 05:51
por hugo
La manera más simple es mas o menos así:

Código: Seleccionar todo

import os

micomando="elscript argumento1 argumento2 ..."

os.system(micomando)
No obstante, en StackOverflow alguien sugirió una manera ingeniosa de usar la clase Popen del módulo subprocess, utilizando una lista para evitar la necesidad de escapar las comillas, espacios y demás (que a veces generan problemas):

Código: Seleccionar todo

def run_script(script, stdin=None):
    """Returns (stdout, stderr), raises error on non-zero return code"""

    import subprocess
    # Note: by using a list here (['bash', ...]) you avoid quoting issues, as the 
    # arguments are passed in exactly this order (spaces, quotes, and newlines won't
    # cause problems):
    proc = subprocess.Popen(['bash', '-c', script],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE,
        stdin=subprocess.PIPE)
    stdout, stderr = proc.communicate()
    if proc.returncode:
        raise ScriptException(proc.returncode, stdout, stderr, script)
    return stdout, stderr

class ScriptException(Exception):
    def __init__(self, returncode, stdout, stderr, script):
        self.returncode = returncode
        self.stdout = stdout
        self.stderr = stderr
        Exception.__init__('Error in script')
La persona adicionalmente recomienda como tarea añadir un método __str__ a la clase ScriptException para poder depurar los scripts, y explica que si no se utilizan stdout=subprocess.PIPE y demás en la declaración de proc, el script se adjuntará directamente a la consola, lo cual puede ser útil para cosas como solicitar una contraseña desde SSH. Finalmente recomienda añadir banderas (flags) para controlar si se desea o no capturar stdout, sdtin y stderr.

Si tienes acceso a Internet, alguien compiló algunas maneras de lograr lo que deseas.