gentoo linux, java, software libre y otras hierbas
Ene, 26 2010 - 11:23 pm

Códigos de shell script útiles en cualquier programa

shell scriptA continuación voy a poner algunos snippets de código de shell script que me han sido siempre útiles cuando escribo algún script. La mayoríá funcinoan en cualquier shell de Unix, aunque algunos requieren que sean ejecutados por Bash.

Evitar que usuarios sin privilegios ejecuten el script

Algunos scripts realizan tareas administrativas por lo cual podríamos querer que solo el usuario root ejecute el script. En ese caso podemos usar algo como esto:

#!/bin/bash
if [[ $EUID -ne 0 ]]; then
echo "Este script debe ser ejecutado por el usuario root" 1>&2
    exit 1
fi

Permitir la ejecución del script solo a un usuario específico

De manera similar al código anterior, podríamos querer que solo un usuario específico ejecute el script. Lo hacemos así:

#!/bin/bash
AUTHORIZED_USER="usuario_permitido"
if [ $USER != $AUTHORIZED_USER ]; then
    echo "Este script debe ser ejecutado por el usuario $AUTHORIZED_USER" 1>&2
    exit 1
fi

Verificar que un servicio/proceso se está ejecutando

Si queremos saber si existen procesos de algún servicio o programa ejecutándose podríamos usar este script (en este caso verifica que el demonio de Apache esté corriendo):

#!/bin/sh
SERVICE='httpd'
if ps ax | grep -v grep | grep $SERVICE > /dev/null
then
    echo "El servicio $SERVICE esta ejecutandose"
else
    echo "Chanfle! El servicio $SERVICE esta detenido"
fi

Verificar que una variable esté asignada/tenga datos

Hay bastantes maneras de hacer esto en shell script… la que considero más sencilla y concisa es esta:

#!/bin/bash
FOO=
: ${FOO:?"No existe la variable FOO o no tiene datos"}
echo "esto nunca se va a imprimir"

El anterior script verifica si una variable existe y tiene datos; si esto no se cumple, el script se cierra. Podemos usar esta variación en donde solo comprobamos que la variable exista, sin importar si tiene datos o no:

#!/bin/bash
FOO=
: ${FOO?"No existe la variable FOO"}
echo "esto si se va a imprimir"

Crear un archivo de bloqueo

A veces debemos asegurarnos que el script no se ejecute dos o más veces simultáneas. Para ello podemos hacer uso de los archivos de bloqueo. Esta es una versión sencilla de un script que nos permite hacer esto:

#!/bin/bash
lockfile=/var/lock/loquesea.lock
if [ ! -e $lockfile ]; then
   touch $lockfile
   echo "hago muchas cosas importantes aqui"
   rm $lockfile
else
   echo "ya hay otro proceso corriendo"
fi

En este caso, se verifica que el archivo loquesea.lock exista. En caso de que exista, el script NO ejecuta sus tareas. Si no existe, crea el archivo, ejecuta las tareas que deba ejecutar y lo elimina.

Pero, esto no es del todo fiable. ¿Qué pasaría si mientras nuestro script se está ejecutando es cerrado abruptamente (con Ctrl^c por ejemplo)? En ese caso el archivo de bloqueo no se borraría, y por lo tanto, no nos permitiría ejecutar el script de nuevo.

Para cubrir esos casos, podríamos hacer uso del comando trap que nos permite ejecutar comandos en caso que nuestro script termine de manera inesperada. Esta es una versión más avanzada que además guarda dentro del archivo de bloqueo el PID del script que lo ejecuta:

#!/bin/bash
lockfile=/var/lock/loquesea.lock
if ( set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null;
then
    trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
    echo "hago muchas cosas aqui tranquilamente"
    rm -f "$lockfile"
    trap - INT TERM EXIT
else
    echo "Ya hay otro proceso de este script ejecutandose"
    echo "corriendo con el PID: $(cat $lockfile)"
fi

Entendamos un poco mejor el comando trap. La sintaxis del mismo es básicamente esta: trap comando signal [signal ...]; donde signal es la señal de terminación que quieres atrapar. Si quieres ver una lista de los signals disponibles puedes ejecutar el comando kill -l. Para el caso anterior se usaron los signals INT (captura la terminación producida por un Ctrl^c), TERM (terminación producida por el comando kill) y EXIT (terminación normal de un script, bien sea porque ya no hay más líneas que ejecutar o porque se encuentra con el comando exit).

Menú de opciones

Para hacer un menú en donde permitimos al usuario seleccionar una serie de opciones podemos usar el siguiente esquema:

#!/bin/bash
clear
while :
do
 echo " Escoja una opcion "
 echo "1. quien soy?"
 echo "2. cuanto espacio tengo"
 echo "3. que es esto?"
 echo "4. Salir"
 echo -n "Seleccione una opcion [1 - 4]"
 read opcion
 case $opcion in
  1) echo "este eres:";
     whoami;;
  2) echo "tienes esto";
     df;;
  3) uname -r;;
  4) echo "chao pues parcero";
     exit 1;;
  *) echo "$opc es una opcion invalida. Es tan dificil?";
     echo "Presiona una tecla para continuar...";
     read foo;;
esac
done

Pedir confirmación antes de ejecutar un script

A veces es útil hacer que el usuario confirme la ejecución de un lote de sentencias, es decir, el típico mensaje que pide al usuario escribir yes o no. Esto lo podemos hacer así:

#!/bin/bash
while true; do
    echo
    read -p "esta seguro de hacer lo que sea que vaya a hacer " yn
    case $yn in
        yes ) break;;
        no ) exit;;
        * ) echo "por favor responda yes o no";;
    esac
done
echo "si se ejecuta esto es que aceptaste"

Fuentes de información

Etiquetas: comandos, linux, script, shell, unix

14 Comentarios | deja el tuyo

3 enlaces entrantes

11 Comentarios en “Códigos de shell script útiles en cualquier programa”

  1. edu dice:

    Hola,

    Muy interasante.

    Gracias

  2. jorge dice:

    otra forma de crear menus sin usar tanto echo es:

    echo ‘
    1.opcion
    2.opcion
    .
    .
    .

    En bash el ‘ , le indica que debe imprimir eso tal cual esta

  3. jorge dice:

    ok, y tambien gracias a ti ya que no se me habia ocurrido lo de EUID.

    Gracias

  4. Sirius dice:

    Muy interesante y útil. a ver cuando me pongo a programar otra vez :P

  5. carnicero dice:

    Carnal estoy empesando en el mundo de shell, me puedes recomendar algun sitio? o algun libro de descarga gratuita, graicas

  6. Miguel dice:

    Esta muy clara tu explicaciòn , es muy buen aporte a la comunidad, sigue asi.
    Gracias

  7. neckro dice:

    Hola, queria saber si tu eres experto en alguna de estas materias en Linux: Shellscripts ,awk, ficheros en C, procesos en c, etc… para poder ayudarme con unos ejercicios mañana.

    gracias de antemano!

    Mi correo es gabri27@hotmail.com, escribeme si tienes conocimientos buenos en algo de lo mencionado arriba, porfavor!

¡Déjanos tu comentario!