Conceptos Básicos de BASH - Parte 4: Variables, Pruebas y Bucles

En esta ocasión me voy a centrar en lo más básico a la hora de crear scripts: las variables, las pruebas y los bucles. La frase para crear archivos de diferentes carpetas también nos hará compañía en otras ingeniosas líneas de comandos. Pero primero, vamos a aprender algunos atajos rápidos que harán que el trabajo con BASH sea más ameno.

Atajos de BASH

Si quieres ejecutar un único comando como un usuario diferente, usa el siguiente comando:

$ su - otheruser -c "command argument"
Para que dos comandos se ejecuten uno tras otro, únelos con ';', por ejemplo:
$ ls /home/odroid/Music; ls /home/odroid/Videos
Si quieres que el segundo comando se ejecute únicamente cuando el primer comando tenga exitoso, utiliza '&&':
$ apt update && apt full-upgrade
Rara vez se utiliza '||', donde el segundo comando sólo se ejecuta cuando el primer comando NO tiene éxito.

En el día a dia, hay determinados pasos que solemos hacer con bastante frecuencia en diferentes contextos. Un ejemplo es ejecutar un comando como root tras haberlo probado con un usuario normal y éste falla por no disponer de los privilegios suficientes.

Después de ejecutar el comando cp somefilewithverylongname.conf /etc para copiar una configuración en el directorio /etc y éste falla, podemos repetir este proceso como root con solo 'sudo !!' - la mayoría de vosotros ya lo sabréis. Los !! significa repetir el último comando y se puede usar con sudo, sin o con otras combinaciones. Alterado con el modificador '!!:p' recupera el último argumento de la línea de comandos. Por lo general, basta con usas la tecla de flecha hacia arriba. ¡Pero en los casos en los que las teclas de flecha no funcionen, por ejemplo en ssh, puede serte de gran ayuda! ! -1 usa el penúltimo comando, que en determinadas ocasiones también es muy útil. Sin embargo, ¿sabías que también puedes reutilizar únicamente el último argumento de un comando?

$ ls /very/long/path/to/a/directory
$ cd !$
se amplía a:
$ cd /very/long/path/to/a/directory
Lo cual te ahorra mucha escritura.
$ ls /very/long/path/to/a/directory
Toneladas de comandos, ninguno de los cuales empiezan con ls
$ !ls
también se amplía a
$ ls /very/long/path/to/a/directory
En el caso de que quieras repetir un comando anterior. Usa '!Rm:p' para examinar el último comando rm antes de ejecutarlo, al igual que ocurre con otros comandos peligrosos. Si solo quieres cambiar algunos detalles del último comando, puede hacer un buscar y reemplazar de los argumentos del siguiente modo:
$ ls /very/long/path/to/a/directory
$ ^very^veryvery
cambia y ejecuta el último comando a
$ls /veryvery/long/path/to/a/folder
Para resumir lo que hemos visto hasta ahora:

  • !! último comando
  • !-1 penúltimo comando
  • !$ último argumento del último comando
  • !command1 última línea con command1
  • ^searchterm^replaceterm reemplaza la primera vez que aparece searchterm por replaceterm

Para moverse por la línea de comando, alt-f mueve el cursor hacia adelante una palabra, alt-b hacia atrás una palabra, ctrl-w borra palabras sueltas hacia atrás, mientras que ctrl-u borra desde la posición del cursor hasta el comienzo de la línea. Puedes moverte al inicio de la línea con ctrl-a y borrar la línea tras el cursor con ctrl-k. Ctrl-t intercambia los dos últimos caracteres antes del cursor para los casos en lo que se suele cometer este error al escribir.

Si quieres algo que lo aligere y sueles escribir erroneamente sl en lugar de ls con bastante frecuencia, también puede instalar sl con apt install sl. No te diré lo que hace, simplemetente pruébalo. Lo más importante, si tienes un nombre de archivo o comando único después de escribir las primeras letras, BASH lo expenderá tras presionar el tabulador. Al presionarlo dos veces, aparecerá una lista de opciones si las primeras letras no son únicas.

Una última cosa, por ahora, el uso de las llaves. Si tienes un archivo llamado abcde.conf y quieres hacer una copia de seguridad del éste con el nombre abcde.conf.bak, todo lo que tiene que hacer es cp abcde.conf{,.Bak} que se amplía a cp abcde.conf abcde.conf.bak al utilizar las llaves. Si deseas listar el contenido del directorio de Videos de los usuarios archie, bert y claude, tienes que colocar éstos dentro de las llaves. El filtro se encarga de hacer el resto.

$ ls /home/{archie,bert,claude}/Videos

Conceptos básicos de programación

Un script BASH es simplemente un archivo de texto con la primera línea #!/Bin/bash y se hace ejecutable con:

$ chmod a+x scriptname.sh
Si creas un directorio llamado bin en tu directorio de inicio, los scripts que estén dentro se podrán ejecutar desde cualquier lugar en Ubuntu. Una entrada especial en ~/.profile se encarga de esto.

Si quieres, incluso puedes programar el juego "Tetris" en BASH en un poco más de 500 líneas, tal y como se muestra en la Figura 1.

Figure 1 - Tetris in BASH on the command line
Figura 1 - Tetris en BASH sobre líneas de comandos

Un típico ejemplo de un script sería hello-world.sh, no olvides ejecutar chmod a+x hello-world.sh después de haberlo guardado desde tu editor de pruebas.

#!/bin/bash
# This script just puts out "Hello World".
echo "Hello World"
Excepto en casos especiales, todo el texto que aparece tras el signo # son comentarios y no se ejecuta.

Si sólo tienes "Hello World" en pantalla, o cualquier otro texto fijo, esto se vuelve aburrido muy rápido. Es el momento de introducir variables BASH para hacer que el script haga algo diferente dependiendo de la entrada. La forma más simple de verlo es de la siguiente manera en nuestro archivo hello-user.sh.

#!/usr/bin/bash
# Greets currently logged-in user
echo "Hello," "$USER"
"Hola, odroid" es el resultado. También podemos definir la variable en el script en lugar de usar una variable de entorno como USER. Aquí tienes nuestro próximo archivo script, hello-user2.sh
#!/usr/bin/bash
# Greets currently logged-in user
user=$(whoami)
echo "Hello," "$user"
"Hola, odroid" es el mismo resultado, pero una variable user es definida por el resultado de la función whoami y luego se imprime con la función echo. También puedes simular esto paso a paso en la línea de comandos sin escribir el script con el editor de texto. Si defines una variable $user, no olvides usar después unset user para dejar limpio el sistema. Hablaremos más sobre las variables en la siguiente parte. Por ahora, vamos a ver un ejemplo de cada componente básico creado en primer lugar para tener una mejor visión de conjunto del típico uso de un script. El siguiente elemento fundamental son las pruebas dentro del script.

En un ejemplo real, vamos a echar un vistazo a un pequeño script para probar la conectividad a Internet, outside-connected.sh:

#!/bin/bash
test=google.com
if
nc -zw1 $test 443
then
echo "we have connectivity"
else
echo "no outside connectivity"
fi
El script define la variable $test como el servidor de google.com, luego usa netcat (nc) en modo escaneo de puertos para un poke rápido, -z es el modo E/S cero, con un tiempo de espera pequeño –w 1 espera como máximo uno segundo. Comprueba Google en el puerto 443 (HTTPS). El resultado depende de si puedes acceder a los servidores de Google o no.

Ahora, veamos los bucles. Con variables, pruebas y bucles, ya tiene cubierto el 95% del uso normal de los scripts. Un simple bucle en un script real sería convertir todos los archivos flac en mp3 de un determinado directorio:

flac2mp3.sh
#!/bin/bash
for i in *.flac
do
ffmpeg -i "$i" -acodec libmp3lame "$(basename "${i/.flac}").mp3"
done
Este script realiza un bucle, convierte y cambia el nombre de cada archivo flac que está dentro del directorio actual. Echa un vistazo a la función basename junto con la variable a la hora de cambiar la extensión .flac a .mp3 en este ejemplo. Estos son los ejemplos más básicos de variables, bucles y pruebas; seguiremos más tarde. En la siguiente parte, continuamos con la programación y también echamos un vistazo a la historia de BASH.

Referencias https://raw.githubusercontent.com/kt97679/tetris/master/tetris.sh https://www.tldp.org/LDP/abs/html/

Be the first to comment

Leave a Reply