miércoles, 24 de marzo de 2021

scripts en Bash... para torpes (IX)

A lo largo de esta serie de entradas al Blog, que debo decir que se me han hecho eternas, he intentado aclarar (y aclararme) de diversos conceptos que veía en los scripts que pasaban por mi mano, con la sana intención de poder llegar a hacerlos yo mismo. Mi conclusión es clara: ha sido una (relativa) pérdida de tiempo, este mundo de la Programación es muy complejo y nadie puede pretender saber de todo por dedicar unas pocas horas. Hombre, algo de culturilla siempre viene bien, y uno puede ‘jugar’ a hacer ‘pequeñas’ cosas en Bash… pero nada ‘mashhh’.
Dice la historia que Colón, en su viaje inicial, desembarcó en una pequeña isla de las Bahamas llamada Guanahani, que luego estuvo en Cuba y en La Española, volviéndose para España para anunciar un Nuevo Mundo… sin pisar el continente americano, que desconocía por completo. Pues esta es mi sensación: que solo he pisado una pequeña isla y que queda muchísimo por descubrir. Así que voy a terminar la aventura (este ‘primer viaje’) con un pequeño resumen de ideas, y unas recomendaciones
9- Recordatorio (Bash… y máshh...)
Y lo primero que quiero hacer es añadir un 'Sumario' de todas las entradas de este tema, que siempre resultará cómodo. Aquí va...
Sumario
 
Aparte de los conceptos básicos, la verdad es que el resumen de las entradas de este Blog es muy simple. Recordemos que...
A) Lo de las variables es un buen invento, y se declaran (básicamente) de estas cuatro posibles formas:
modalidad sintaxis

Para recibir un ‘output’
desde el teclado

read -p "introduce lo que quieras usar: ″ nombre_variable
o bien…
“escribe el dato que quieras: ” && read nombre_variable
Para indicar lo que
contendrá la variable
y se ajusta el tamaño
nombre_variable=$(comando u órdenes a ejecutar)
o bien (con comillas invertidas)…
nombre_variable=`comando u órdenes a ejecutar`

B) El buen uso de los diversos caracteres (comillas, dobles comillas, comillas invertidas, paréntesis, corchetes y claves, así como los espacios en blanco, es fundamental. Recordar (sobre todo si creas tus ‘borradores’ en Libreoffice, que un tipo de letra ‘monospace’ facilita mucho ver los espacios vacíos, etc. Y que, en LibreOffice, las comillas dobles « “ ... “ » son ‘tipográficas’ (o inglesas), y suelen ser fuente de error al usarlas en el script. Las ‘buenas son las ‘rectas’, que son las que salen en la consola y en los editores sencillos de texto, y que se pueden obtener por su código Unicode, apareciendo si escribes (mientras mantienes pulsadas Mayusc y Ctrl ) la tecla u y luego el número 2033.

C) Los operadores de redireccionado ( > ; y | ) y los lógicos ( && y ||) son muy importantes
echo ‘creo un archivo’ > ~/Escritorio/prueba.txt && echo y le añado más texto >> ~/Escritorio/prueba.txt

D) Es importante conocer y saber usar comandos. Lo malo es que hay muchísimos, y que o los usas continuamente, o se te olvidan. Quizás, como simple acercamiento, es bueno recordar que ‘grep’ te permite buscar coincidencias con un patrón dado, ‘cut’ lee datos de archivos y te los presenta, y el comando ‘find’ busca según las reglas de busqueda que le indiques (y find (al contrario que grep) si admite comodines). Sencillos ejemplos
ls ~/Imágenes/ | grep .png
cat /etc/apt/sources.list
find ~/ -iname *virtualbox*

Nota: la opción -iname (del comando find) busca archivos ‘por nombre’, sin importar que aparezcan con mayúsculas o minúsculas). Es interesante conocer estos comandos, y sus ‘man’

E) Las variables de entorno también pueden ser ínteresantes. En particular, puede serlo el uso (dentro del propio script, u orden) de los argumentos ($1, $2…) que son los parámetros que se introducen junto a su orden de ejecución. Por ejemplo… escribir en consola
sh multiplicar.sh 740 43
si hemos creado un script 'multiplicar.sh' con
#!/bin/bash
PROD=$(($1*$2))
echo $PROD


F) El uso de herramientas como ‘zenity’ (‘sudo apt install zenity’) o similar, puede hacer divertido (entre otras cosas) introducir, desde dentro del script, estos argumentos. O las variables. Por ejemplo...
DESDE=$(zenity --entry --title="Pág. inicial" --text="Iniciar en página...") && echo $DESDE

G) Si tienes que crear alguna orden condicional, lo más habitual es hacerlo con if (si…) then (entonces…) y, si acaso, else (caso contrario haz...) o elif (y si no, haz…). Las sintaxis son:
if [ condiciónA ]; then ‘mandatoX’; fi
if [ condiciónA ]; then ‘mandato X’; else ‘mandato Y’; fi
if [ condiciónA ]; then ‘mandato X’; elif ‘mandato Y’; elif ‘mandato Z’….; fi

(Porque los bucles do… done, while, until… a nivel básico se usan poco y el condicional case, aunque interesante, parece algo complejo para usarlo un novato)

H) Las funciones, para ahorrar un código repetitivo, son fundamentales, pero al mencionado nivel básico, puede que se usen poco. Por recordarlas, se declaran (normalmente al principio del script) con
nombre_función () {
comando1;comando2;...
}

Nota: la primera línea puede ser, también y así nos ahorramos los paréntesis ()...
function nombre_funcion {
y se invocan escribiendo, simplemente, el nombre de la función.
Y, sobre todo, recordemos la importancia que puede tener la ‘Biblioteca de Funciones’, que se pueda crear en un archivo de texto (llamado, por ejemplo ‘mis_func’) y luego invocarlo, con el comando ‘source’, al principio de cualquier script, con
#!/bin/bash
source ./mis_func

(y aquí seguiría el desarrollo del script, que de esta forma podrá usar las funciones incluidas en ese archivo ‘mis_func’ sin más que invocarlas).
También (para quienes quieran seguir hasta un nivel avanzado) comenté que existían los arrays, o matrices.


G) Y como pequeño ejemplo, muy ilustrativo, voy a referenciar aquí una entrada a este Blog, de hace 3 años, exactamente ésta, donde exponía un script complejo, un ejemplo de ‘lista de diálogo’ hecho con zénity… y que es quizás es bueno verlo ahora que sabemos algo más de funciones, variables… y hasta del condicional ‘case’, porque seguro que lo entenderemos perfectamente (yo, entonces, sospecho que solo me limitaba a copiar y pegar órdenes, sin ‘entenderlas’)

H) También es bueno recordar las operaciones aritméticas...

Operaciones aritméticas
SUM=$(($num1 + $num2)) && echo $SUM
(y, de forma similar, la resta, la multiplicación,con ‘ * ’, y la división, con ' / ')
DIF=$(($num1 - $num2)) && echo $DIF
para obtener el valor absoluto en la resta…
DIF_abs=$(($num1 - $num2)) && echo ${DIF#-}
Y para poder operar con decimales (por ejemplo)...
SUM=$(echo "scale=2; 3.45+8.23" | bc) && echo $SUM
PROD=$(echo "scale=2; 3.45*8.0" | bc) && echo $PROD
DIV=$(echo "scale=2; 345/36" | bc) && echo $DIV

y los operadores para la comparación...


Incluso podría ser interesante tener a mano...
comando 'date': formatos más usados
día de la semana: %a (abreviado) - %A (completo)
día del mes: %d
Mes: %b (abrev.) - %B (completo) - %m (en número)
%Y Año completo.
%H hora (de 00 a 24) %I hora (de 01 a 12)
Ver (en consola) ‘ahora...’
date +"%d de %B de %Y"
date +"%d-%m-%Y"
date +"%H horas y %M minutos"
date +"%H:%M"


J) Y decía, finalmente, que hay otros lenguajes’ para crear scripts, seguramente basados en bash, y posiblemente más ‘directos’ que bash para ciertas cosas. Es bastante común ver scripts desarrollados, por ejemplo, en Python. Por supuesto no voy a hablar de ellos más que ‘para tener una culturilla’. Así que solo diré que los scripts en python (en python3) se caracterizan por…
- su extensión es *.py
- su ‘shebang’ suele ser #! /usr/bin/python, (o #!/usr/bin/env python)
- se ejecutan con la orden… python3 nombre_archivo.py
- el conocido comando ‘echo’ aquí se llama ‘print’
- y la triple « > > > » es el prompt de la ‘consola interactiva’ de Python. Se accede escribiendo
python

en la consola habitual. Ya en esa ‘consola interactiva’ verás ese prompt y cualquier orden que escribas se ejecutará. Por ejemplo si escribes 4+7 y das a enter, te aparecerá el resultado.
las ‘variables’ se declaran, simplemente, encribiendo...
nombre_variable = número o “cadena de texto”
o, como hacíamos es Bash, tomando lo tecleado, ahora con el mandato ‘input’
nombre_variable = input ("Por favor entre su nombre: ")
(el nombre_variable debe empezar por una letra, o por un guión bajo, nunca por un número ni por una serie de palabras reservadas (on unas 30), ni puede tener acentos (tildes), o signos concretos, como el famoso « $ »).
y se invocan, simplemente, con su nombre_variable.
Las variables, en Python, son mucho más ‘potentes’ que en Bash. Pueden contener cualquier clase de números (enteros, decimales, imaginarios, en notación científica, con precisión arbitraria, en base decimal o en otras bases, etc.), cadenas de texto (una sola letra o más letras, del juego de caracteres ASCII occidental o del juego de caracteres Unicode, etc), conjuntos de números o texto (matrices, listas, tuplas, etc.) o estructuras más complicadas (punteros, diccionarios, etc.)
Cada tipo de información se almacena (internamente) de forma distinta, por lo que existen diferentes tipos de variables para cada tipo de información. Esto podemos saberlo con el comando
type (nombre_variable)
Python comparte con Bash, en general, todo el tema de comandos, operadores, condicionales, etc aunque, por supuesto, con sus ‘matices’ específicos. No es el caso hablar de ello, hay mucha info sobre Python en Google. Pero, por ejemplo, lo que decía: comprobar si un número existe en una lista y montarse un script es aquí mucho más fácil que en Bash, utilizando el operador booleano « in ».
Un ejemplo muy sencillo...
Para comprobar si un socio de una biblioteca puede sacar un libro, porque no tiene tiene pendiente de devolución algún otro, puede hacerse este pequeño script”:
#! /usr/bin/python
sociospendientes = [103, 109, 250, 266, 279, 292, 305, 318, 331, 344, 357, 370, 383, 396, 409]
numero = int(input("Escriba el número del socio: "))
# (esta es la forma como hemos declarado las dos variables) Y ahora...
if numero in sociospendientes:
print("Lo siento, no puede sacar más libros hasta que no devuelva los prestados")
else:
print("De acuerdo ¿Qué libro quiere sacar?")


Bueno, pues aquí lo dejo.
Se me ocurre que algún día tendré que crear una entrada al Blog para tener referenciados mis ‘pequeños scripts’, que me son útiles unos para usarlos en un lanzador el propio Menu, otros como lanzador en el escritorio, otros como (como vimos) dentro de una acción en el menú contextual de Nemo… y otros, porque me divierte hacerlos, o para algun caso concreto. Es una buena forma de tenerlos muy a mano.

Así que sospecho que ‘to be continued...’

 

Ir al Sumario (del tema)

 

No hay comentarios:

Publicar un comentario