domingo, 7 de marzo de 2021

scripts en Bash... para torpes (VI)

Hoy vamos a zambullirnos en el tema de crear órdenes, que en los scripts es bastante frecuente. Pero partimos de la premisa de que somos ‘torpes’ y de que intentamos hablar en un idioma que, los que no hemos estudiado programación, desconocemos. Y estamos en lo de siempre: que para hablar ‘con fluidez’ lo importante es tanto tener un buen vocabulario (en el caso, conocer los comandos), como dominar la gramática (las reglas y convenciones de la Programación).
Además, sospecho que la ‘facilidad’ de crear una orden para algo que se te ocurra hacer depende del idioma de programación. Como sencillo ejemplo, crear una orden para comprobar si un número (que digas) está incluido en una lista (predeterminada) de números, parece ser que es bastante complejo de hacer, en Bash… pero es mucho más sencillo en otros lenguajes de programación, como Python.
En fin, que vamos a ver estas cosas, un poco por encima, que así por lo menos ‘acostumbramos el oido ’ y entenderemos algo mejor lo que puede decir un script. Así que...
6- Aprendiendo a dar ordenes

Introducción
Ya hemos dicho que, en programación, el input (canal STDIN) está formado por los mandatos (y los operadores, argumentos...) que introduzcas (o encadenes, vía tubería) en el sistema.
Estos mandatos pueden ser muy sencillos, como un simple comando, por ejemplo…
cal
o dar una orden más o menos compleja, como
date +"%d-%b-%Y" && date +"son las %H:%M"
o incluso complicarlo más, y hacerlo (por ejemplo) a través de ‘funciones’, que luego veremos.

Algo que se usa mucho en programación son las ordenes para establecer condiciones.
Las órdenes más básicas son el for…do, el if...then, el case...esac, el do...done, el while (y until)-do-done...que, si interesan, se pueden consultar por ejemplo aquí (o, simplemente, buscando por Google, que hay muchísima información). En general podemos dividirlas en dos grandes grupos: las órdenes cíclicas, o bucles, y las ordenes condicionales.
Vamos a ver alguna, aunque sea un poco por encima.


Los ciclos for...do
La cĺásica orden ‘for...do’, sirve para indicar que, iterativamente, ‘por un valor determinado de una variable, haz (siempre) esta acción’. Como todas las órdenes cíclicas (llamadas también ‘bucles’), es bastante usada, no solo en scripts. Por ejemplo, el for, el until, el while, que veremos ahora, sospecho que se usan mucho, desde consola, en diagnósticos técnicos de funcionamiento (donde, por supuesto, no me voy a meter).

Estas iteraciones, o bucles, terminan o bien cuando un ‘contador’ llegue a determinado valor, o bien por el comando ’break’, etc. Y terminarán cuando añadas ‘done’. También pueden complementarse con el condicional ‘if…’ (y si…). Como digo, los ciclos se utilizan cuando se necesita que se vaya ejecutando repetidas veces un bloque de instrucciones, hasta que (o mientras que), se cumpla una condición dada.
Una sintaxis de uso muy sencilla, si llamamos ‘iniciador’ (o ‘lanzador de la iteración’) al ‘elemento esperado’, lo sencillo es poner ‘i’, es, en una lista o condición a cumplir, esta:
for (iniciador) in (lista o condición); do (instrucciones); done
Mira este ejemplo: (puedes copiarlo directamente a la consola, y dar al ENTER para que se ejecute, recuerda que la notación « ~/…» significa « /home/tu_usuario/ »)
for i in ~/Documentos/*.pdf;do echo $i;sleep 0.7;done
que irá revisando la carpeta ~/Documentos/ y sacará en pantalla (echo $i) todos los archivos con extensión .pdf que vaya encontrando en ella. (si se hubiese puesto ~/*/*.pdf sería ‘en todas las carpetas de /home’)


Iterando con números
Las iteraciones suelen hacerse con números. Se pueden hacer de varias formas...
A veces se ve, en sintaxis similar a la empleada en el lenguaje C+, un iteración de este tipo...
for (( inicializador; condición; paso de iteración )); do instrucciones; done
ejemplo:
for (( i=10; i<20; i++ )); do echo $i; done
(este ejemplo crea una serie, que inicia en 10 y termina con el 19, incrementándose de 1 en 1).

Pero, con números, es mucho más versatil hacerlo con el comando «seq» y la fijación del «rango».
Una iteración de números, con comando ‘seq’ seguido del ‘rango’ (el rango es ‘lo que queremos hacer’) se plantearía, genéricamente, así:
for i in $(seq rango); do #Instrucciones; done
La variable (seq rango) puede tomar alguna de estas formas:
(seq último_valor)
(seq primer_valor último_valor)
(seq primer_valor incremento último_valor)

Veamos unos ejemplos...
a) la expresión de arriba podíamos, y desde luego parece mucho más cómodo, así:
for i in $(seq 10 19); do echo $i; done
y nos da, efectivamente, la lista de números del 10 al 19. Y, por poner otros ejemplos que aclaran lo dicho...
for i in $(seq 15); do echo $i; done
nos lista los primeros 15 números (desde 1), y...
for i in $(seq 23 23 200); do echo $i; done
nos presentaría la lista de los multiplos de 23, hasta el 200.
Una aplicación práctica: podemos declarar una variable con este comando. Por ejemplo, definimos...
tramoA=$(seq 23 1 50)
y esta variable la podremos utilizar más cómodamente si necesitamos esa lista de números. Y además, así los presenta en horizontal. Por ejemplo, por acortarlo, copia y pega…
tramoA=$(seq 21 1 38); echo $tramoA

Los bucles while y until
Lo que hace el ciclo while es permitir que se ejecute una orden (o un bloque de instrucciones) mientras se cumpla la condición definida.
Su sintaxis es también muy sencilla:
while [ condición ]; do //Bloque de instrucciones; done

Es decir, comprueba que se cumple la condición dada y entonces ejecuta las instrucciones del segmento de código contenido entre las palabras do y done, también iterativamente (hasta que deje de cumplirse la condición).
Until hace lo contrario que while: permite que se ejecute algo… mientras NO se cumpla una condición dada. Es decir, verifica que la condición sea FALSA para ejecutar el mandato incluido entre el do y el done. Así que…
until [ condición ]; do //Bloque de instrucciones; done
Todas estas ordenes iterativas, para que no se vuelvan un bucle continuo, cuando no las pones un límite tipo ‘seq [primer valor] [incremento] [último valor] que comentaba, admiten el mandato «break». Incluso el ‘anidado’. 

Pero esto ya son temas más complejos...

 

Ir al Sumario (del tema)

 

 

 

No hay comentarios:

Publicar un comentario