¿Cómo ejecutar scripts bash usando Python?

Si está utilizando Linux, definitivamente le encantarán los comandos de shell.

Y si está trabajando con Python, es posible que haya intentado automatizar las cosas. Esa es una manera de ahorrar tiempo. También puede tener algunos scripts de bash para automatizar las cosas.

Python es útil para escribir scripts que bash. Y administrar los scripts de Python es fácil en comparación con los scripts bash. Le resultará difícil mantener los scripts de bash una vez que esté creciendo.

Pero, ¿qué sucede si ya tiene scripts de bash que desea ejecutar con Python?

¿Hay alguna forma de ejecutar los comandos y scripts de bash en Python?

Sí, Python tiene un módulo integrado llamado subproceso que se usa para ejecutar los comandos y scripts dentro de los scripts de Python. Veamos cómo ejecutar comandos bash y scripts en scripts de Python en detalle.

Ejecutando Comandos Bash

Como ya habrá visto, el subproceso del módulo se usa para ejecutar los comandos y scripts de bash. Proporciona diferentes métodos y clases para el mismo.

Hay principalmente un método y una clase para conocer desde el módulo de subproceso. Se ejecutan y Popen. Estos dos nos ayudan a ejecutar los comandos bash en los scripts de Python. Vamos a verlos uno por uno.

subproceso.ejecutar()

El método subprocess.run() tomará una lista de cadenas como argumento posicional. Esto es obligatorio ya que tiene el comando bash y argumentos para ello. El primer elemento de la lista es el nombre del comando y los elementos restantes son los argumentos del comando.

Veamos un ejemplo rápido.

import subprocess
subprocess.run(["ls"])

La secuencia de comandos anterior enumera todos los elementos en el directorio de trabajo actual tal como se encuentra la secuencia de comandos. No hay argumentos para el comando en el script anterior. Solo hemos dado el comando bash. Podemos proporcionar argumentos adicionales al comando ls como -l, -a, -la, etc.

Veamos un ejemplo rápido con argumentos de comando.

import subprocess
subprocess.run(["ls", "-la"])

El comando anterior muestra todos los archivos, incluidos los archivos ocultos, junto con los permisos. Hemos proporcionado el argumento la que muestra archivos y directorios con información adicional y archivos ocultos.

Podemos terminar cometiendo algunos errores al escribir los comandos. Los errores aumentarán de acuerdo con los errores. ¿Qué pasa si quieres capturarlos y usarlos más tarde? Sí, podemos hacerlo usando el argumento de palabra clave stderr.

Veamos un ejemplo.

import subprocess
result = subprocess.run(["cat", "sample.txt"], stderr=subprocess.PIPE, text=True)
print(result.stderr)

Asegúrese de no tener el archivo con el nombre sample.txt en el directorio de trabajo. El valor del argumento de palabra clave stderr es PIPE, que ayuda a devolver el error en un objeto. Podemos acceder a él más tarde con el mismo nombre. Y el texto del argumento de la palabra clave ayuda a decir que la salida debe ser una cadena.

De manera similar, podemos capturar la salida del comando usando el argumento de palabra clave stdout.

import subprocess
result = subprocess.run(["echo", "Hello, World!"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print(result.stdout)

subproceso.ejecutar() – entrada

Puede dar entrada a los comandos usando el argumento de palabra clave de entrada. Daremos entradas en un formato de cadena. Por lo tanto, debemos establecer el texto del argumento de la palabra clave en True. Por defecto lo toma en bytes.

Veamos un ejemplo.

import subprocess
subprocess.run(["python3", "add.py"], text=True, input="2 3")

En el programa anterior, el script de Python add.py tomará dos números como entrada. Le hemos dado la entrada al script de Python usando el argumento de palabra clave de entrada.

subproceso.Popen()

La clase subprocess.Popen() es más avanzada que el método subprocess.run(). Nos da más opciones para ejecutar los comandos. Crearemos una instancia del subproceso. Popen() y la usaremos para varias cosas, como conocer el estado de la ejecución del comando, obtener resultados, dar entradas, etc.

Hay varios métodos de la clase subprocess.Popen() que necesitamos conocer. Veámoslos uno por uno junto con los ejemplos de código.

Espere

Se utiliza para esperar hasta que finalice la ejecución del comando. Las siguientes líneas de la secuencia de comandos de Python no se ejecutarán hasta que se complete el comando anterior que se escribe después del método de espera. Veamos el ejemplo.

import subprocess
process = subprocess.Popen(["ls", "-la"])
print("Completed!")

Ejecute el código anterior y observe la salida. Verás que el mensaje Completed! se imprime antes de la ejecución del comando. Podemos evitarlo usando el método de espera. Esperemos hasta la finalización del comando.

import subprocess
process = subprocess.Popen(["ls", "-la"])
process.wait()

print("Completed!")

Si ve el resultado del código anterior, se dará cuenta de que la espera realmente está funcionando. La declaración de impresión se ejecuta después de completar la ejecución del comando.

comunicar

El método de comunicación se utiliza para obtener la salida, el error y dar entrada al comando. Devuelve una tupla que contiene salida y error respectivamente. Veamos un ejemplo.

import subprocess
process = subprocess.Popen(["echo", "Hello, World!"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
result = process.communicate()
print(result)

subproceso.Popen() – entrada

No podemos pasar la entrada a la clase Popen directamente. Necesitamos usar el argumento de palabra clave llamado stdin para dar la entrada al comando. La instancia de la clase Popen nos proporcionará el objeto stdin. Tiene un método llamado escribir que se usa para dar la entrada al comando.

Como discutimos anteriormente, tomará las entradas como objetos similares a bytes de manera predeterminada. Por lo tanto, no olvide establecer el texto del argumento de la palabra clave en True al crear la instancia de Popen.

Veamos un ejemplo.

import subprocess
process = subprocess.Popen(["python3", "add.py"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
process.stdin.write("2 3")
process.stdin.close()
print(process.stdout.read())

encuesta

El método de sondeo se utiliza para verificar si la ejecución del comando se completó o no. Este método devolverá Ninguno si el comando aún se está ejecutando. Veamos un ejemplo.

import subprocess
process = subprocess.Popen(['ping', '-c 5', 'geekflare.com'], stdout=subprocess.PIPE, text=True)
while True:
    output = process.stdout.readline()
    if output:
    	print(output.strip())
    result = process.poll()
    if result is not None:
        break

En el código anterior, hemos usado el comando ping con 5 solicitudes. Hay un bucle infinito que itera hasta la finalización de la ejecución del comando. Hemos utilizado el método poll para comprobar el estado de ejecución del comando. Si la encuesta del método devuelve un código distinto de Ninguno, la ejecución se completa. Y el bucle infinito se rompe.

Ejecución de secuencias de comandos Bash

Hemos visto dos formas de ejecutar los comandos. Ahora, veamos cómo ejecutar los scripts de bash en los scripts de Python.

El subproceso tiene un método llamado llamada. Este método se utiliza para ejecutar los scripts bash. El método devuelve el código de salida del script bash. El código de salida predeterminado para los scripts bash es 0. Veamos un ejemplo.

Cree un script bash con el nombre Practice.sh de la siguiente manera.

#!/bin/bash

echo "Hello, World!"
exit 1

Ahora, escriba una secuencia de comandos de Python y ejecute la secuencia de comandos bash anterior.

import subprocess
exit_code = subprocess.call('./practice.sh')
print(exit_code)

Obtendrá el siguiente resultado una vez que ejecute el script de Python anterior.

Hello, World!
1

Conclusión

Hemos visto cómo ejecutar comandos bash y scripts en Python. Puede usarlos para automatizar las cosas de manera más eficiente.

Codificación feliz 👨‍💻