Contenidos
1 Introducción
2 Conceptos
2.1 Shells
2.2 Ejecución
2.3 Estructura
2.4 Formatos
3 Variables
3.1 Variables de Entorno
3.2 Manejo de Strings
3.2.1 String entre comillas simples
3.2.2 String entre comillas dobles
3.2.3 Escape de Caracteres
4 Estructuras de Control
4.1 Condicionales
4.2 Bucles
4.3 Comparación de archivos y variables con el comando test
Introducción
Los Shell Scripts son pequeños, pero a la vez muy útiles, archivos de texto que contienen una serie de comandos para shell que el sistema ejecuta ordenadamente, de arriba abajo. Para editarlos, tan solo hace falta un editor de textos, como Emacs o Vi. Se guardan con extensión “.sh” y se ejecutan desde la Shell mediante el comando: sh nombre de script.sh o mediante el operador “./” nombre de script.sh. Los scripts, se comportan de igual manera que los comandos de la shell.
Conceptos
Shells
Si se desea saber qué Shells se tienen instalados en una distribución GNU/Linux sólo se tiene que teclear el comando:
cat /etc/shells
La salida de la instrucción anterior podría ser:
/bin/sh
/bin/bash
/sbin/nologin
/bin/ash
/bin/bsh
/bin/ksh
/usr/bin/ksh
/usr/bin/pdksh
/bin/tcsh
/bin/csh
/bin/zsh
Ejecución
Es importante también saber que un script puede ejecutarse en primer o en segundo plano:
-
Primer plano (foreground): se lanza introduciendo el nombre del script, pero hasta que el script no termine no se devolverá el control de la shell al usuario.
-
Segundo plano (background): se lanza igual que el anterior, pero añadiendo a continuación un &. El control de la shell pasa inmediatamente al usuario (este proceso es normalmente usado para procesos de larga duración)
Estructura
La estructura de un shell script es la siguiente:
- El nombre del archivo debe tener la extensión .sh
- En su primera línea debe tener:
#!/bin/sh
Esto indica el tipo de shell que estamos programando.
- Instrucciones de shell
Ejemplo:
#!/bin/sh
echo “HOLA MUNDO”
Formatos
Comentarios: Los comentarios en shell script se indican con el operador “#” al inicial la línea que se desea como comentario.
Sensibilidad de Caracteres: En shell script se hace diferencia entre mayúsculas y minúsculas.
Tipos de Datos: No es necesario definir tipos de datos para las variables, sólo se requiere de la asignación de valores.
Cadenas de Caracteres: Las cadenas de caracteres se escriben entre dobles comillas: “”
Variables
En los shell scripts no es necesario definir los tipos de datos de las variables, sólo se requiere de la asignación por medio del operador =.
Ejemplo: variable=10
Para visualizar el contenido de una variable se utiliza:
Ejemplo: echo $variable
Para borrar el contenido de una variable se utiliza:
Ejemplo: unset variable
A continuación se muestra una tabla con una serie de variables especiales que nos serán de utilidad a la hora de escribir nuestros scripts:
VARIABLE |
DESCRIPCION |
$0 |
Nombre del Shell-Script que se está ejecutando. |
$n |
Parámetro o argumento pasado al Shell-Script en la posición n, n=1,2,… |
$# |
Número de argumentos. |
$* |
Lista de todos los argumentos. |
$? |
Salida del último proceso ejecutado. |
$$ |
Número de identificación del proceso (PID) |
$! |
Número del último proceso invocado por la shell |
Variables de Entorno
Por defecto, cuando asignamos un valor a una variable, es local, es decir, es conocida por esa shell, pero si se abre otra shell a partir de la que estamos, estas nuevas “subshells” desconocen el valor de las variables que hemos asignado anteriormente.
En cambio, las variables del entorno están disponibles para las subshells, es decir, los valores de estas variables son conocidos por los procesos hijos de la shell.
Para hacer que una variable se almacene en el área de entorno, se utiliza el siguiente comando:
Ejemplo: export variable=10
Para conocer todas las variables de entorno definidas debemos ejecutar el comando env, cuya salida es similar a la siguiente:
[usuario@srv-prueba01]/u02/prueba> env
HOSTNAME=srv-prueba01
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
QTDIR=/usr/lib/qt-3.3
SSH_TTY=/dev/pts/1
PWD=/u02/prueba
EDITOR=/usr/bin/emacs
LANG=C
PS1=[$USER@$HOSTNAME]$PWD>
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SHLVL=1
HOME=/u02/prueba
Manejo de Strings
En las shell scripts nos podemos encontrar con diferentes tipos de cadenas de caracteres y aquí analizaremos aquellas entre comillas simples y dobles y cómo utilizar las secuencias de escape.
String entre comillas simples
Las comillas simples nos sirven para hacer que la shell interprete lo encerrado entre ellas como una expresión literal, ya sean variables, comodines u otras expresiones, es decir, el contenido no es interpretado por la shell.
Para entenderlo mejor, imaginemos que deseamos crear una carpeta de nombre # o *. Si lo intentamos, es decir si tecleamos mkdir #, la shell indicará un error. Sin embargo si escribimos mkdir ‘#’, el intérprete de comandos tomará el carácter # como un literal y podremos crear la carpeta con ese nombre.
String entre comillas dobles
Este tipo de cadenas de caracteres permiten la sustitución de parámetros, la sustitución de comandos y la evaluación de expresiones aritméticas, pero ignoran las sustituciones de tilde, expansión de caracteres comodines, aliases y la división de palabras vía delimitadores.
Las comillas simples dentro de las comillas dobles no tienen efecto. Se pueden incluir comillas dobles dentro de una cadena con comillas dobles anteponiendo un \.
Es decir, se produce sustitución de variable (el signo de pesos se interpreta) por ejemplo, podremos ejecutar ls “$PWD” y nos devolverá correctamente el listado de archivos del directorio en que nos encontramos, pero si hacemos ls “*”, el comodín será tomado como un literal.
Escape de Caracteres
Una barra inversa permite escapar al carácter que acompaña, por ejemplo:
echo “\$alida con \” escapes \” ”
En el ejemplo anterior, los caracteres $ (pesos) y ” (comillas) han sido escapados, por lo que no se interpretará una variable $alida ni darán error las dobles comillas incluidas.
Estructuras de Control
Cómo en cualquier lenguaje de programación, necesitaremos una serie de estructuras de control que permitan modificar el flujo de ejecución de las instrucciones de nuestro script.
Condicionales
if: Corresponde a la instrucción más sencilla y su sintaxis es:
if [ condicion ]
then
sentencias
fi
if/else:
if [ condicion ]
then
sentencias 1
else
sentencias 2
fi
if/elif/else:
if [ condicion1 ]
then
sentencias 1
elif [ condicion2 ]; then
sentencias 2
else
sentencias 3
fi
case: En esta estructura cuando se encuentre un patrón que coincida, se ejecuta la lista de comandos hasta los “;;” y se termina la ejecución de case.
case expresion in
1)
sentencias 1
;;
2)
sentencias 2
…
*)
sentencias n
;;
Esac
Bucles
for: El bucle ‘for’ es una estructura de control iterativa que permite repetir una sección del programa, un número fijo de veces. Su sintaxis pueden ser las siguientes:
for variable in [lista]
do
sentencias
done
for (( inicio ; condicion_termino ; incremento ))
do
sentencias
done
Ejemplos:
for variable in `seq 1 10`
do
echo $variable
done
for ((variable=0; variable <= 10; variable++))
do
echo $variable
done
while: Sirve para repetir un bucle mientras se cumpla la condición:
while [ condicion ]
do
sentencias
done
Ejemplo:
num=0
while [ $num -le 10 ]
do
echo “numero: $num”
num=`expr $num + 1`
done
until: Igual que while, pero el ciclo se ejecutará mientras la condición sea falsa:
until [ condicion ]
do
sentencias
done
Ejemplo:
num=0
until [ $num -eq 10 ]
do
echo “numero: $num”
num=`expr $num + 1`
done
Comparación de archivos y variables con el comando test
Para evaluar expresiones condicionales dentro de los “if” u otras estructuras, se utiliza el comando “test”. Veamos un resumen en la siguiente tabla:
Expresión |
DESCRIPCIóN |
-b archivo |
Cierto si archivo existe y es un dispositivo de bloques. |
-c archivo |
Cierto si archivo existe y es un dispositivo de caracteres. |
-d archivo |
Cierto si archivo existe y es un directorio. |
-e archivo |
Cierto si archivo existe. |
-f archivo |
Cierto si archivo existe y es un archivo normal. |
-g archivo |
Cierto si archivo existe y tiene el bit de grupo activado. |
-k archivo |
Cierto si archivo tiene el bit de sticky activado. |
-L archivo |
Cierto si archivo existe y es un enlace simbólico. |
-p archivo |
Cierto si archivo existe y es una tubería nombrada. |
-r archivo |
Cierto si archivo existe y es legible. |
-s archivo |
Cierto si archivo existe y su tamaño es mayor que cero. |
-S archivo |
Cierto si archivo existe y es un socket. |
-t [df] |
Cierto si df está abierto en un terminal. Si df es omitido, se toma 1 (salida estándar) por defecto. |
-u archivo |
Cierto si archivo existe y tiene el bit de usuario activo. |
-w archivo |
Cierto si archivo existe y es escribible. |
-x archivo |
Cierto si archivo existe y es ejecutable. |
-O archivo |
Cierto si archivo existe y es propiedad del identificador efectivo del usuario. |
-G archivo |
Cierto si archivo existe y es propiedad del identificador efectivo del grupo. |
archivo1 -nt archivo2 |
Cierto si archivo1 es más reciente (en base a la fecha de modificación) que archivo2. |
archivo1 -ot archivo2 |
Cierto si archivo1 es más antiguo que archivo2. |
archivo1 -ef archivo2 |
Cierto si archivo1 y archivo2 tienen el mismo número de dispositivo y de nodo-i. |
-z cadena |
Cierto si la longitud de cadena es cero. |
-n cadena |
Cierto si la longitud de cadena no es cero. |
cadena |
Cierto si la longitud de cadena no es cero. |
cadena1 = cadena2 |
Cierto si las cadenas son iguales. |
cadena1 != cadena2 |
Cierto si las cadenas no son iguales. |
! expr |
Cierto si expr es falsa. |
expr1 -a expr2 |
Cierto si expr1 y expr2 son ciertas. |
expr1 -o expr2 |
Cierto si expr1 o expr2 son ciertas. |
arg1 OP arg2 |
OP es uno de los siguientes valores:
-eq igual que, -ne distinto, -lt menor que, -le menor o igual que, -gt mayor que, -ge mayor o igual que.
arg1 y arg2 pueden ser enteros positivos, enteros negativos |
Ejemplos:
a.
if [ -r «script.out» ]
then
echo “Archivo existe”
else
echo “Archivo no existes”
fi
b.
if test -r “script.out”
then
echo “Archivo existe”
else
echo “Archivo no existes”
fi
c.
read variable
if test $variable -le 10
then
echo “Menor o igual que 10″
else
echo “Mayor que 10″
fi
Comments
3 Comments
RSS