martes, 16 de febrero de 2021

scripts en Bash... para torpes (IV)

Hay que ir entrando en materia. Y verás que van ‘espesándose’ las ideas (o ‘mis’ ideas, claro). Lo que sigue (excepto quizás, la ampliación al concepto de ‘variables’) es un buen ejemplo de ello. Pero seguiré tratando de aclarar conceptos, adornándolas con algún que otro ejemplo de algún pequeño script más o menos interesante, al menos para que, viendo cosas, ‘no nos suene a chino’’. Hoy toca...
4- Entrando en materia: variables y argumentos


Las variables
Esto de ‘las variables’ ya anticipé que es un concepto clave. Ya sabemos que se invocan con
$nombre_variable
pero vamos a extendernos un poco más en el tema de cómo se declaran.
Por centrar ideas, empecemos diciendo que hay dos tipos de variables: las variables propias de entorno, algunos las llaman ‘de ambiente’ (en este caso, serían las propias de Bash), y las variables de usuario, que son las que crea, para usarlas, el propio el programador.
Variables propias del entorno
El uso de las (llamadas) variables propias del entorno Bash, que los expertos suelen utilizar, pero que, para un novato, quizás sea algo complejo de entender, se basa en que los ‘argumentos’ (que trataré de explicar luego) se pueden tratar por separado, e identificarse con una variable.
Así, se predefine que, por ejemplo, las variables llamadas $1, $2, $3..., $n nos invoque al 1º, 2º, 3º… de los argumentos introducidos en un script. Y que, por ejemplo,
$0 nos invoca (o informa) del nombre del programa en ejecución,
$# indica el número de argumentos/parámetros introducidos en la aplicación
$? indica el resultado de la ejecución del comando anterior: si se ha realizado correctamente esta variable tendrá el valor cero, y valor uno si ha habido algún error.
$$ nos indicará el PID de la aplicación., etc.
Por eso los ‘conocedores’ aprovechan estas variables propias del entorno para utilizarlas en el desarrollo de sus programas, o scripts.


Las variables de Usuario
En cuanto a las variables ‘de usuario’, que son la que crea, por propio interés, el programador, ya comentamos que se identifican con la palabra (el nombre de la variable) que se indique. Está convenido que esta palabra (o palabras) no puedan contener espacios vacíos, ni caracteres especiales, ni empezar con números (para evitar confundirse con variables específicas, que los contienen). Hay quien recomienda que se escriban en minúsculas, pero a otros les gusta hacerlo en mayúscula, para ‘verlas’ mejor en un desarrollo.
Cómo declarar una variable de usuario
O sea, cómo vincular unos datos a una variable. Lo podemos hacer de varias formas:
a) Introduciendo los datos de manera directa, por teclearlo (o copiando y pegando) en el terminal, para que lo lea directamente el propio intérprete, mediante el comando ‘read’, que ya conocemos
Se usa esta sintaxis: (por ejemplo)
read -p "introduce (o copia y pega) lo que quieras usar: " nombre_variable
con lo que queda definida la variable, que tomará el valor de lo que hayamos introducido/copiado y pegado y que con escribir $nombre_variable, lo invocamos. Por ejemplo, este pequeño script, que yo llamo, info.sh, da una información detallada de cualquier paquete (instalado o no) de los repositorios de Debian (que tengamos activados, claro)
#!/bin/bash
read -p "escribe o copia y pega el nombre del paquete cuya información quieres obtener: " COD
sudo aptitude show $COD
read -rsp $'Pulsa cualquier tecla para salir...\n' -n 1 key

y la verdad es que lo uso bastante, y lo tengo incorporado, en un lanzador, como ‘Herramienta del sistema’ ,en el ‘Menu’ de mi Debian-Cinnamon.
NOTA: las variables también se pueden declarar con la secuencia
echo “escribe el dato que quieras: ” && read nombre_variable

(donde considera el dato que hayas escrito (una edad, año, nombre…) como variable, de nombre el que le asignes en ‘read...’ Por ejemplo, copia y pega en consola...
echo “escribe tu nacionalidad: “ && read NACIO && echo eres de nacionalidad $NACIO
que se ve también con bastante frecuencia.
b) La segunda gran forma de declararlas es, sencillamente, describiéndola
nombre_variable=(lo que queramos que represente)
Atención, no puede haber espacios ni antes ni detrás del signo ‘ = ‘, y podemos ‘declarar’ la variable de dos formas: o bien con el símbolo $ y paréntesis, así...
nombre_variable=$(comando u órdenes que queramos incluir)
o bien, con comillas invertidas (y no hace falta inicial con $)
nombre_variable=`comando u órdenes que queramos incluir`
(en este caso es muy util emplear (se ve mucho mejor) un tipo de letra ‘monospace’
Por ejemplo, copia y pega en consola...
FECHA=$(date +%A,%d-%B-%Y) && echo $FECHA
FECHA=`date +%A,%d-%B-%Y` && echo $FECHA

(Y así, en vez de tener que introducir todo el dato, basta invocar la variable $FECHA)
Por cierto, si quisiésemos poner solo la hora, sería
HORA=$(date +%T) && echo Son las $HORA
(o con (date +%H:%M) para poner solo horas y minutos)


Consejo final: Si un comando fuese largo, o complejo, es muy frecuente que se escriba distribuyéndolo en varias líneas. Y cada línea tiene que acabar con una antibarra ( \ ) para indicar continuidad.
Por ejemplo, aquí presento un script para tener un bonito calendario perpetuo, donde hay un comando largo, que se escribe en dos líneas:
#!/bin/bash
if
read -p "introduce el año: " year && \
read -p "introduce el número del mes (1, 2...12): " mes
then
zenity --calendar --year=$year --month=$mes
fi

(este script, si lo llamamos, por ejemplo, calperpet.sh, y si tenemos instalada la herramienta ‘zenity’ (si no, ‘sudo apt install zenity’), puede ser divertido ejecutarlo (incluso tenerlo en el Menu como una ‘herramienta’, creando un lanzador), porque es, como dije, un interesante calendario perpetuo.


 Los argumentos (o parámetros)
Vamos a seguir ‘espesando’ conceptos...
Se llaman argumentos a los valores (‘parámetros posicionales’) que introducimos, a través de la consola, a nuestro programa (o a nuestro script), cuando lo vamos a ejecutar (y antes de ello). 
Un sencillo ejemplo: si escribimos, en consola
sh mi_script.sh hola 100
estamos mandando ejecutar un script e introduciendo dos argumentos, ‘hola’ y ‘100’. Los argumentos deben ir separados por un espacio y, si fuesen una frase, ésta se pondrá entre comillas.
Como decía antes, al hablar de las variables de entorno, en Bash, estos argumentos, o parámetros posicionales (primer parámetro, segundo, tercero… ) los podemos tratar por separado, invocándolos como variables, con las expresiones $1,$2...$9 , y de esta forma se da una gran flexibilidad a nuestros scripts ya que mediante ellos podemos indicar con qué dato queremos trabajar a continuación, porque….
$1, $2, $3… son los argumentos 1º, 2º, 3º… del script. A partir de 9 hay que ponerlos entre claves: ${12} (o ponerlo así ${1,2,….12} 

Por ponerlo sencillo: podíamos hacer un script genérico llamado 'multiplica.sh' donde, con escribir 'sh multiplica num1 num2' nos apareciese en pantalla el resultado... para cualquier valor de esos números, porque el script se haría usando las variables $1 y $2 (los dos argumentos).
Existen, además, otros argumentos (parámetros) especiales que por su posible interés, también tienen su identificación para poder invocarlos fácilmente. Por ejemplo...
$0 indica el nombre del fichero en ejecución,
$? indica el valor devuelto por el ultimo comando (0 si se ejecutó correctamente (true), o 1, si 'false')
$# indica el número de parámetros que contiene el script
$$ Nos indicará el PID de la aplicación.
$! Nos indicará el último PID/proceso que se ha arrancado en segundo plano.
$* contiene todos los parámetros, considerándolos como un solo valor
$@ lo mismo, pero los considera como valores separados, por lo que puede iterar sobre ellos.
veremos que, en algún ejemplo, salen a relucir estos parámetros posicionales en esta forma de invocarlos, separadamente, como variables.


Termino ya: voy a echar un poco de imaginación e inventarme (como ejemplo) una historia (que espero que valga): supongamos que creamos un script para una oficina, y que llamaremos Registro.sh. En esta oficina, según llega una persona, le vamos a pedir nombre y dos apellidos, y DNI, y además vamos a anotar el día y la hora, y la razón de su presencia. Estos datos van a servir para llevar un registro, crear una ficha, o lo que sea.
Así que cuando llegue alguien, el empleado escribe, en consola
sh Registro.sh d h
y lo ejecuta
El script 'Registro.sh' es, por ejemplo, este:
#! /bin/bash
d=$(date +"%d de %B de %Y")
h=$(date +"%H:%M")
echo
read -p "Digame nombre y dos apellidos: " NOM AP1 AP2
read -p "Digame su DNI: " DNI
read -p "Digame la razón de su visita: " RAZ
echo
echo "$d, a las $h\nEl Sr/Sra $NOM $AP1 $AP2, con DNI $DNI\nDesea: $RAZ" >> REGISTRO.txt
echo
echo "\e[1;33mAhora podrás ver que, la primera vez, \nse te ha creado el archivo REGISTRO.txt en la ruta \ndonde hayas guardado el script\ny este archivo te irá recogiendo los nuevos registros efectuados"
echo "esto es lo que está escrito"
echo "\e[1;35mY AHORA VAMOS A VER LA HISTORIA DE LOS ARGUMENTOS"
echo "en este caso se han introducido $# argumentos o parametros"
echo "estos son todos los argumentos introducidos": $@
echo "NOTA: Si se hubiese puesto alguno más, tras d y h, \nno se usaría en el script, pero aparecería aquí"
echo "el primer argumento es '$1' que sirve para anotar que hoy es... $d"
echo "y el 2º es '$2' y sirve para anotar que en estos momentos son las $h horas"
echo "si has escrito más argumentos, de momento el script no los ha necesitado"
echo "Fijate que en principio, los datos introducidos \nuna vez que funciona el script, no son argumentos sino variables"
echo
echo "Bueno, y etc...¿Queda más o menos claro?"
echo
echo
echo "\e[1;31mPUES, PARA TERMINAR, vamos a abrir el archivo 'REGISTRO.txt' y GUARDAR LOS CAMBIOS"
echo (por cierto, podrías ver por pantalla lo que contiene en archivo escribiendo 'cat REGISTRO.txt')

Ahora, copialo en el Bloc de Notas, archívalo como Registro.sh y escribe en consola
sh Registro.sh d h

Pues eso ¿Queda más o menos claro? 

 

Ir al Sumario (del tema)

 

 

No hay comentarios:

Publicar un comentario