Python y Bash Scripting
Dado que en este foro somos personas de bien y nuestro sistema operativo es una distribución de Linux, nos encontraremos con que Bash es el lenguaje nativo del sistema y consiste en crear archivos o scripts con la capacidad de ejecutar comandos de Linux, permitiéndonos automatizar tareas del sistema sin tener que ingresar constantemente los mismos comandos una y otra vez.
Podemos combinar los comandos y los resultados de la ejecución de los mismos con elementos típicos de la programación como el uso de variables, operaciones matemáticas, estructuras condicionales y bucles, dandonos el poder de operar nuestro sistema de manera más sofisticada.
En este momento deben estar preguntándose “¿Y qué tiene que ver esto con la programación en Python?” y es que este lenguaje cuenta con una librería muy útil que nos permite ejecutar comandos en bash o incluso ejecutar scripts de bash utilizando comandos de Linux, aumentando aún más el poder del programador para lograr sus objetivos o extender sus capacidades.
Para este curso no vamos a aprender cómo programar en bash, pero sí veremos como Python puede ejecutar comandos o scripts y utilizar esos resultados en nuestro software.
Para poder ejecutar un comando de Linux en Python, primero debemos importar la librería os:
import os
os.system("sudo apt update && sudo apt upgrade")
Así de sencillo tenemos un script de Python que actualiza nuestro sistema operativo y sólo utilizamos dos líneas de código.
Utilizando el formato de las cadenas de texto, podemos modificar estas para crear, por ejemplo, archivos de texto que contengan valores específicos:
import os
resultado = 3 + 4
os.system(f"echo '{resultado}' > archivo.txt")
os.system("cat archivo.txt")
Ahora vamos a ver cómo guardar nuestra dirección IP en una variable de Python. Para ello, vamos a utilizar la librería subprocess:
- Primero vamos a tener establecer el comando en bash que nos retornará nuestra dirección IP:
ip a | grep wlan0 | awk 'NR==2' | awk '{print $2}' | awk '{print $1}' FS='/'
Traducción:
ip a | Muestra las interfaces de red |
grep wlan 0 | Filtra por la interfáz ‘wlan0’ |
awk ‘NR==2’ | Filtra por la segunda fila, se puede reemplazar con ‘tail -n 1’ |
awk ‘{print $2}’ | Imprime el segundo argumento de la fila |
awk ‘{print $1}’ FS=‘/’ | Imprime el primer elemento, tomando como delimitador el caracter especificado |
cut -d ‘/’ -f 1 | Corta el argumento en el caracter especificado y toma el elemento 1 de dicha división |
Teniendo identificado el comando que necesitamos, en Python vamos a crear un programa que ejecuta el comando, almacena el resultado en una variable a través de una función y luego la imprime por pantalla:
# Importamos la librería:
import subprocess
# Ejecutamos el método check_output de dicha librería para ejecutar el comando y almacenar el output en la variable
mi_IP = subprocess.check_output ("ip a | grep wlan0 | awk 'NR==2' | awk '{print $2}' | awk '{print $1}' FS='/'", shell=True)
# Ahora podemos imprimir el resultado del comando:
print (f"Mi dirección IP es: {mi_IP}")
Vamos a elevar el nivel un poco más y vamos a crear un script en bash que nos permita identificar a todos los hosts activos en nuestra red. No se preocupen por entender bash en este momento, lo explicaré en el curso de ese lenguaje… cuando al fin pueda hacerlo jajajaja
- Primero vamos a crear un script en bash:
hostScan.sh
#!/bin/bash
#Colours
greenColour="\e[0;32m\033[1m"
endColour="\033[0m\e[0m"
redColour="\e[0;31m\033[1m"
blueColour="\e[0;34m\033[1m"
yellowColour="\e[0;33m\033[1m"
purpleColour="\e[0;35m\033[1m"
turquoiseColour="\e[0;36m\033[1m"
grayColour="\e[0;37m\033[1m"
orangeColour="\e[0;208m\033[1m"
declare -a ports=( $(seq 1 65535) )
function ctrl_c(){
echo -e "\n\n${redColour}[!] Saliendo...${endColour}\n"
tput cnorm; exit 1
}
# Ctrl + C
trap ctrl_c SIGINT
function checkHost(){
for i in $(seq 1 254); do
timeout 1 bash -c "ping -c 1 $1.$i &>/dev/null" && echo -e "${greenColour}[+]${endColour}${grayColour} Host $1.${endColour}${turquoiseColour}$i${endColour}${grayColour} - ${endColour}${greenColour}ACTIVE${endColour}" &
done
}
if [ $1 ]; then
checkHost $1 &
else
echo -e "${redColour}[!]${endColour}${grayColour} Uso:${endColour}${turquoiseColour} $0${endColour}${orangeColour} <Primeros tres octetos de IP, ej: 192.168.1>${endColour}\n"
fi
wait
- Ahora vamos a ejecutar ese script de Bash con un script de Python:
pythonScript.py
# Importamos la librería:
import os
os.system("/home/[usuario]/hostScan.sh")
Al ejecutar el comando, nos devolverá un error avisándonos de que no tenemos permisos para ejecutar el script de Bash. Los permisos son un tema en Linux que requieren de bastante atención y que tiene su complejidad, por lo que voy a omitir las explicaciones en este momento.
Para resumirlo de manera sencilla, el script de Bash no se ejecutará porque no posee permisos de ejecución. Para solucionar esto, deberemos cambiarle los permisos de ejecución con el siguiente comando:
chmod +x hostScan.sh
-Una vez hecho esto, el script de Python ejecutará el script de Bash, el cual comenzará a listarnos todas las direcciones IP activas en nuestra red.
Esta es una herramienta muy simple pero a la vez muy útil que nos permitirá ver la cantidad de equipos conectados a nuestra red y la dirección IP que posee.
Al involucrar Bash, las cosas se complejizan mucho más y el tema se vuelve por demás extenso. Desafío a cualquiera que este haciendo el curso a que pruebe y experimente esta combinación y también, que comparta sus descubrimientos respondiendo a este tema.