Scripts Linux Bash Segunda Entrega

Comenzamos este segundo post “Scripts Linux Bash Segunda Entrega” en el apartado de Scripting para Linux usando Bash, haciendo un repaso y ampliando las bases un poco.

Añadimos el concepto de parámetros de un Script, como los parámetros que pasamos a cualquier otro comando.

Veremos también la estructura condicional if, que permite ejecutar ciertas acciones si se cumple un TEST, y opcionalmente (si no se cumple) ejecutar otras acciones distintas (correctoras o informadoras por ejemplo).

Repaso de las bases del scripting

Se denomina Shell Script a un fichero, de texto plano, que contiene órdenes del propio Sistema Operativo, para ser ejecutadas por el Shell (intérprete de comandos o de órdenes).

Cualquiera de los Shells que ofrezca nuestra distribución GNU/Linux es susceptible de ser ampliado, haciendo nuestros propios “comandos nuevos” mediante la programación de Shell Scripts.

Podéis obtener una lista de los interpretes de comandos que tiene instalada vuestra distribución echando un vistazo a uno de los ficheros de configuración /etc/shells:

cat /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
/bin/zsh
/usr/bin/zsh

Además de los propios comandos del Sistema Operativo, todo lenguaje de programación tiene estructuras de control propias del lenguaje (condicionales, bucles, ..) que iremos desgranando durante este curso. En este articulo introduciremos la if (si se cumple esto haz estas cosas, si no se cumple haz estas otras cosas), que en Bash tiene la pinta:

if [ TEST ]; then
   <hacer si se cumple TEST>
else
   <hacer si no se cumple TEST>
fi

Los Scripts son muy utilizados para automatizar tareas administrativas en servidores o en ordenadores de escritorio.

En el capítulo de hoy vamos a hablar de:

  • Cómo pasar y recoger parámetros al script y
  • la estructura condicional if

Script de Ejemplo

Imaginemos el siguiente Script que podéis confeccionar con cualquier editor de texto, y que utilizaremos en los siguientes apartados (lo podemos llamar miscript.sh):

#!/bin/bash
#miscript.sh
#mi primer script
echo -n "Fecha y hora: "
date
echo -n "Numero de usuarios del sistema:"
who | wc -l
echo -e "Directorio actual:\c "
pwd
exit 0

Comentarios

Las líneas que comienzan por el carácter # (almohadilla) son comentarios. El Shell no las interpreta (no las ejecuta). Debemos utilizar los comentarios para documentar nuestros Scripts.
Un caso especial es el uso de #! en la primera línea para indicar el intérprete con que se ejecutará el script. Si no se coloca esta línea, el script se interpretará con el Shell activo.

Ejecución de un script

En el caso de los scripts Bash, los podemos ejecutar de varias formas:

1 – Creando un Shell no interactivo y redirigiendo su entrada estandar (stdin) al script:

bash < miscript.sh

2 – Creando un Shell no interactivo y pasándole el script como argumento:

bash miscript.sh

3 – Dando permiso de ejecución al script y ejecutándolo como una orden. Esta es la más adecuada y utilizada:

chmod u+x miscript.sh
./miscript.sh

el shell detecta que se trata de un shell script y crea otro shell para que lo ejecute.

4 – Con la orden “.” punto:

. miscript.sh

Ejecuta el script sin crear un shell hijo.

La salida al ejecutar nuestro Script de ejemplo, en cualquier caso, debería ser parecida a esto:

Fecha y hora: mié abr  1 15:43:56 CEST 2015
Numero de usuarios del sistema:2
Directorio actual:/home/jose/sospedia-scripts

Directorio para Scripts

Conviene tener todos los scripts localizados en una carpeta y luego incluir la misma en la variable PATH. Para ello con la orden mkdir de creación de directorios nos hacemos una carpeta de trabajo, donde iremos ubicando nuestros Scripts:

mkdir ~/scripts

Creo en mi carpeta personal (~) la subcarpeta scripts, donde a partir de ahora iré dejando mis Scripts. El carácter ~ se consigue con la tecla ALTGr+4 (en el teclado alfanumérico).

Variables

Todas las variables son de tipo alfanumérico. Por tanto no se distinguen tipos de datos. Empiezan por letra o _ (guión bajo). Se suelen utilizar mayúsculas, aunque es indiferente, eso sí, recordar que Linux es un entorno sensible a mayúsculas/minúsculas (case sensitive).

La variable queda definida al darle valor usando una expresión de este tipo:

variable=valor

Crea la variable asignándole la cadena de caracteres valor. Si variable ya existe modifica su valor.

Ejemplos: Salid a la consola, y asignad valor a dos variables MIDIR y YO de esta forma:

MIDIR=/home/usuario/scripts
YO=$USER

Con el comando echo podemos ver su contenido, anteponiendo el simbolo del dolar al nombre de la variable $MIDIR o $YO:

echo $MIDIR
echo $YO

Referencias a variables

Se referencian cómo acabamos de ver utilizando el caracter $ delante del nombre de la variable. Vamos a añadir al script que venimos usando estas líneas antes de la orden exit 0

MIDIR=/home/usuario/scripts
YO=$USER

#asignaciones con dobles comillas ya que tienen referencias a otras variables
DIR="El directorio del usuario $YO esta ubicado en $MIDIR, y su contenido es:"

#ver contenidos de variables
echo $DIR

#utilizar variables
ls -l $MIDIR

Tenéis varios comandos además para trabajar con variables de entorno:

  • set: Muestra todas las variables y su valor, definidas en el shell actual (variables locales)
  • env: Permite visualizar las variables de entorno
  • unset: Elimina una variable: (unset variable)

Variables posicionales

Podemos acceder a los argumentos de un script mediante las variables posicionales $1, $2, .., $9, ${10}, …

Cada $i hace referencia al parámetro i-ésimo.

Cuando tiene más de un dígito se usan las llaves para romper la ambigüedad.

Además, tenemos otras variables especiales:

  • $0 : nombre del script
  • $* : todos los argumentos (no contiene el nombre del script)
  • $# : número de argumentos.
  • $? : estado de terminación de la última orden
  • $$ : pid del proceso en ejecución

Ejemplo variables.sh

Vamos a crear en nuestra carpeta el script variables.sh y después lo ejecutaremos pasándole parámetros o argumentos.

#!/bin/sh
#variables.sh
#Variables posicionales
echo Argumentos de la orden: $*
echo Numero de argumentos: $#
echo comando $0
echo arg 1 $1
echo arg 2 $2
echo arg 3 $3
echo agr 4 $4
echo estado: $?
echo pid: $$
echo Orden: $0 $*
exit 0

Ahora lo ejecutamos:

./variables.sh 10 a hola ?

El resultado algo así:

Argumentos de la orden: 10 a hola ?
Numero de argumentos: 4
comando ./variables.sh
arg 1 10
arg 2 a
arg 3 hola
agr 4 ?
estado: 0
pid: 5118
Orden: ./variables.sh 10 a hola ?

Control de flujo

El shell posee sentencias para el control del flujo similares a las existentes en otros lenguajes de programación.

if .. then

if [ condición ]
then
  hacer si se cunple
else
  ordenes a ejecutar si no se cunple
fi

if

Para ver la estructura if vamos ha realizar un script suma.sh al que se le han de pasar dos números cómo parámetros al ejecutarlo.

#!/bin/bash
#suma.sh
#script que suma los dos parametros
if [ $# -eq 2 ]
then
    let sum=$1+$2
    echo "$1 + $2 = $sum"
else
    echo "Introduce dos argumentos numéricos, gracias."
fi
exit 0

El script anterior, se debe ejecutar así:

./suma.sh 4 5

y produciría una salida por pantalla así:

4 + 5 = 9

Donde:

  • 4 es el primer parámetro ($1),
  • 5 es el segundo parámetro ($2)
  • y $0 contiene el nombre del script.

En cambio si lo ejecutamos así:

./suma.sh

No se cumple la condición del if:

if [ $# -eq 2 ]

que está preguntando ¿El número de parámetros es igual a 2?

Por lo tanto ejecuta la parte else:

else
    echo "Introduce dos argumentos numéricos, gracias."

Y responde así por pantalla:

Introduce dos argumentos numéricos, gracias.

Se puede compactar un poco el código del if de Bash:

if [ $# -eq 2 ]; then
    let sum=$1+$2
    echo "$1 + $2 = $sum"
else
    echo "Introduce dos argumentos numéricos, gracias."
fi

Subiendo el then arriba

; then

Quedando la orden if así:

if [ $# -eq 2 ]; then

Y esto es todo, espero que os haya gustado. En el próximo post os hablo de la Variable de entorno PATH que determina los caminos donde busca el Sistema Operativo los ejecutables cuando le pedimos que ejecute alguna orden.

[ < Primer Post ] [ Variable de entorno PATH >]

3 comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.