LPIC-1 Tema 105.2: Modificar o escribir scripts sencillos

Siguiente artículo sobre las certificaciones LPIC-1, con la introducción al tema 105.2. Es decir, lo referente a personalizar y escribir pequeños scripts muy simples. Por supuesto, el shell que abarcan estas certificaciones LPI es Bash, por lo que las preguntas irán orientadas a scripts para este sh.

Para ello, los candidatos a administradores de sistemas GNU/Linux deberán demostrar sus habilidades sobre esta temática, haciendo uso de una sintaxis correcta (loops, tests,…), saber evaluar los valores retornados por el script, así como los errores que pueda dar, conocer el shebang adecuado, etc.

¿Qué es un script?

Un script o guión es un código escrito en un lenguaje de programación o con una serie de comandos u órdenes relativamente simples. Se diferencian de los códigos fuente de los lenguajes de programación compilados en que no necesitan ser compilados. Será un intérprete el que ejecute las órdenes escrita en este script, de ahí que los lenguajes de programación de este tipo se conozcan como lenguajes interpretados (Ruby, Python, AWK, Java, Perl, PHP,…).

En el caso que nos toca, el intérprete será el propio shell, es decir, Bash será el encargado de interpretar y ejecutar las órdenes que contiene el script.

Como podrás comprobar, los scripts se componen de comandos que usas en el shell tradicionalmente. El objetivo de introducirlos dentro de un script es automatizar ciertas tareas o ejecutarlos en «lotes» para ahorrar trabajo al administrador de sistemas, especialmente para tareas de mantenimiento. Verás que son super prácticos…

Shebang, extensión y ejecución

Antes de comenzar a ver algunos scripts de ejemplo y ciertas funciones que debes conocer, tienes que conocer bien estos conceptos:

  • Extensión: este tipo de scripts suele tener la extensión .sh. Puedes usar cualquier editor de texto para escribir las órdenes y guardar el fichero con el nombre que prefieras seguido de .sh para que luego el shell Bash pueda interpretarlo. Por supuesto, debe tener permisos de ejecución…
  • Syscall exec(): en Linux esta será la llamada al sistema que se encargará de comprobar si el fichero es de texto, un binario, o si contiene órdenes sin compilar. En caso de ser un script le pasa el contenido al intérprete adecuado para que lo ejecute. Una de las cosas necesarias para identificar al intérprete es el shebang.
  • Shebang: se necesita poner una especie de cabecera que identifica al intérprete, es decir, a Bash en este caso. Siempre comienza por #! seguido de la ruta del binario donde se aloja el intérprete en el sistema. Si no la conoces podrías usar el comando which bash para localizarlo. Por ejemplo, para Bash sería:
#El shebang por defecto es:
#!/bin/bash

#Podría ser también el enlace simbólico hacia el shell por defecto
#!/bin/sh

#E incluso este otro si el binario no está en una ruta absoluta conocida:
#!/usr/bin/env bash
  • Ejecución: para ejecutar el script en Bash, puedes usar varias formas. Por ejemplo, si tienes que ejecutar un script llamado ejemplo.sh, podrías con algunas de estas opciones (podrías usar sudo o ejecutarlos como root si es necesario):
#Opción básica
./ejemplo.sh

#Ejemplo con sh y usando la ruta completa (si se encuentra en otro directorio o no está en $PATH)
ssh ~/ejemplo.sh

#Ejemplo con sh con la opción -x para que muestre los comandos en ejecución
sh -x ejemplo.sh

#Ejemplo con source
source ejemplo.sh

#Exec permite que el proceso a ejecutar sustituya al proceso anterior y tome su PID:
exec ejemplo.sh
  • #: para los comentarios dentro de un script se puede preceder el mensaje de este símbolo para que el intérprete ingore esa línea. Por ejemplo:
#Esto es un comentario

Sintaxis e introducción al shell scripting

Más información – Shell scripting y variables de entorno

Para crear un script, es muy sencillo. Por ejemplo, para crear un Hola mundo podrías hacer lo siguiente:

nano hola.sh

Dentro del editor puedes escribir las órdenes, en este caso un simple echo para mostrar el mensaje Hola mundo:

#!/bin/bash
echo Hola mundo

Podrías sustituir lo anterior para escribirlo en forma de función en vez de tipo lista. Por ejemplo (por cierto, no cambies el orden de la llamada a la función antes de la propia declaración de la función o dará error):

#!/bin/bash
funcionprueba(){
   echo "Hola mundo"
}
funcionprueba

También podrías seguir agregando más comandos, y no solo el echo. Por ejemplo:

#!/bin/bash
funcionprueba(){
   echo "Hola mundo"
   echo "Fin"
   clear
}
funcionprueba

Sea como sea, guarda el contenido y ahora le das permisos de ejecución y lo puedes ejecutar para ver el resultado:

chmod +x hola.sh

./hola.sh

Por último, deberías saber que puedes usar todos los comandos conocidos para ejecutarlos dentro del script. Además de ellos, puedes usar estas otras funciones o comandos muy prácticos:

  • for: bucle para incrementar o disminuir los contadores. Por ejemplo, en este script lo único que se irá mostrando la cuenta atrás, pero podrías usarlo para ejecutar otras órdenes…
#!/bing/bash
for (( contador=10; contador>0; contador-- ))
do
     echo -n "$contador "
done
  • while: otra forma de usar bucles, esta vez para que se mantenga mientras que se cumpla, contador, o se verifica alguna condición. Por ejemplo, para que muestre una serie de números del 0 al 10:
#!/bing/bash
contador=0
terminar=10

while [ $terminar -ge $contador ]
do
     echo $contador
     let contador=$contador+1
done
  • until: ciclo o bucle que ejecutará el bloque de instrucciones que contiene mientras no se cumpla una condición dada. Es decir, la diferencia con while es que verifica si la condición es falsa, y si lo es ejecuta las instrucciones entre do y done. Si fuese verdadera no lo haría. Por ejemplo:
#!/bing/bash
contador=0
terminar=10

until [ $terminar -ge $contador ]
do
     echo $contador
     let contador=$contador+1
done
  • if – then – else: condición. Por ejemplo, imagina que quieres detectar si un servidor está conectado o no. Para ello, puedes usar el comando ping con la IP del servidor que quieres comprobar y si se cumple la condición de que ping falle, entonces muestra el primer mensaje, en otro caso (si ping obtiene conexión) muestra el mensaje tras else:
#!/bing/bash
ping -c 1 216.58.198.195
if [ $? -ne 0 ]; then
echo "Servidor desconectado"
else
echo "Servidor conectado"
fi
  • test: es un comando que evalúa expresiones y resulta práctico para las condiciones. Por ejemplo, se puede combinar con until de esta forma para contar de 3 en 3 hasta 75:
#!/bin/bash
x=2
until test $x –eq 75
do
     x=`expr $x +3`
     echo $x
done
  • read: permite leer valores introducidos, por lo que es práctico para evaluar estos datos y tomar decisiones en función de ello. Por ejemplo, en este script se seguiría ejecutando el bucle hasta que no introduzcas el número que se te pide (el 735):
#!/bin/bash
numero=735
echo “Introduce un número:”
while true;
do
     read valor
     if [ $numero = $valor ]; then
     echo “Acertaste”
     break
     else
     echo “Mala suerte...Inténtalo de nuevo”
     fi
done
  • select: se puede usar para crear menús interactivos para tu script. Es una estructura de control que mostrará los ítems y se iniciará la variable correspondiente al valor introducido por el usuario. Por ejemplo:
#!/bin/bash
clear
PS3=”¿Qué desea hacer?:”
select opcion in “1.Crear directorio” “2.Borrar” “3.Salir”
do
     case $opcion in
         1) mkdir /home/directorio ;;
          2) rm /home/directorio ;;
          3) exit ;;
          *) echo “No es un ítem válido del menú” ;;
     esac
done
  • break y continue: comandos que pueden combinarse con los anteriores para romper los bucles o comprobar nuevamente la condición del bucle respectivamente. Por ejemplo, puedes crear un script para que si detecta una q salga o si detecta una c siga:
#!/bin/bash
while [ $# -gt 0]
do
     if [ $1 = “q” ]
     then
     break
     fi
     echo El parámetro es: $1
     shift
done
#!/bin/bash
while [ $# -gt 0]
do
     if [ $1 = “c” ]
     then
     shift
     continue
     fi
     echo El parámetro es: $1
     shift
done
  • sleep y wait: esperan algo, en el primer caso pausará durante un tiempo especificado y en el segundo caso espera a que un proceso termine. Por ejemplo:
#!/bin/bash

echo “Espera 5 segundos”
sleep 5
echo “¡Listo!”
#!/bin/bash

echo "Esperando un proceso" &
process_id=$!
wait $process_id
echo "Finalizado con estatus $?"
  • Agregar parámetros (interactividad): se puede usar $1, $2, $3,… para leer parámetros que introduzcas tras el comando de ejecución como opciones. Por ejemplo, podrías crear un script para hacer cópias de seguridad usando la orden ./nombre_script.sh /ruta/de/entrada /ruta/de/salida. Es decir, especificar la ruta donde se encuentre lo que quieres copiar y la ruta donde se guarde la copia. Para eso, deberías usar algo así:
#/bin/bash
echo "¿Quieres copiar $1 a $2 ? - Pulsa Ctrl+C para salir si no es lo que quieres." 
sleep 3
echo "Copiando..."
tar -cvpzf $2.tar.gz $1
echo "La copia de seguridad de $1 se completó con éxito."
notify-send -t 8000 "Copia $1 realizada"
exit
  • seq: puede generar una secuencia de números. Por ejemplo, puedes eliminar los ficheros de que se llamen nombre1 a nombre4 de un directorio:
#!/bin/bash
for n in ‘seq 4’
do
     rm fichero$n
done
  • También puedes usar las salidas de otros comandos, tuberías, redirecciones, etc., dentro de tu script. Por ejemplo, en el siguiente caso se puede usar date para obtener la fecha actual y usar dicha fecha para nombrar una supuesta cópia de seguriad:
#!/bin/bash 

fecha=`date "+%d-%m-%y_%H-%M-%S"` 
nombre="respaldo_$fecha.tgz" 
destino="~/Backups" 
respaldo="copiaSeguridad" 

#Creará el directorio destino y empaqueta "copiaSeguridad" en un tarball 
mkdir -p "$destino" tar cfvz "$destino/$nombre" "$respaldo"
  • ||, &&, ;, …: representan operadores. Por ejemplo, || es  el operador lógico OR, mientras que && es el operador lógico AND. Aquí tienes algunos ejemplos de usos:
#En este caso mostrará la palabra hola, puesto que false no se cumple nunca y por tanto ejecuta echo
false || echo "hola"

#En este caso no mostrará nada porque true siempre se cumple
true || echo "hola"

#Muestra el resultado porque lo anterior se cumple
true && echo "hola"

#No se muestra el resultado de echo porque lo anterior no tiene éxito (false)
false && echo "hola"

#Se muestra el mensaje en ambos, ya que ; da igual lo que ocurra antes
false ; echo "hola"
true ; echo "hola"

Existen otras funciones, operadores, etc., pero estos son los más básicos para ir comenzando.

En un futuro publicaré más scripts prácticos, por ahora cierro con este último ejemplo de algo más práctico para no seguir alargando este artículo…

Recuerda que puedes también automatizar la ejecución de estos scripts con cron, crontab, agregarlos para que se ejecuten durante el arranque o durante el apagado del sistema, etc.

Isaac

Apasionado de la computación y la tecnología en general. Siempre intentando desaprender para apreHender.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

A %d blogueros les gusta esto:

Si continuas utilizando este sitio aceptas el uso de cookies. más información

Los ajustes de cookies de esta web están configurados para "permitir cookies" y así ofrecerte la mejor experiencia de navegación posible. Si sigues utilizando esta web sin cambiar tus ajustes de cookies o haces clic en "Aceptar" estarás dando tu consentimiento a esto.

Cerrar