Tema 7 Linux Shell Scripts

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 24

IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

CURSO 2012/2013

Sistemas
informáticos

Tema 7

Página 3 Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.CURSO 2012/2013

Nuestro primer script ............................................................................................................. 2


Uso de Variables en los Scripts. Expansiones........................................................................ 3
$(orden) ................................................................................................................................ 3
$((operación aritmética))....................................................................................................... 4
let. bc. ................................................................................................................................... 5
Funciones ................................................................................................................................. 6
Estructuras Condicionales ..................................................................................................... 8
If ........................................................................................................................................... 8
If..else.................................................................................................................................. 10
if..elif..else........................................................................................................................... 10
Case ..................................................................................................................................... 14
Estructuras iterativas. (Bucles) ............................................................................................. 16
For ........................................................................................................................................ 16
while y until ........................................................................................................................ 20
select ................................................................................................................................... 22
Paso de parámetros a un script ............................................................................................. 25
Valores devueltos por las órdenes ........................................................................................ 26
Un script completo de ejemplo ............................................................................................. 28

Página 4 Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.CURSO 2012/2013

NUESTRO PRIMER SCRIPT.

Los scripts no son más que ficheros de texto ASCII puro, que pueden ser creados con cualquier
editor del que dispongamos (vi, nano, gedit, emacs, etc.). Crea un fichero de texto de nombre
primero.sh, con el siguiente contenido:

#!/bin/bash
echo “Hola Mundo”

La primera línea sirve para indicar que shell utilizamos (en nuestro caso bash) y donde puede
ser encontrado en nuestro sistema (para saberlo, podemos hacer locate bash ). Esta línea
debe ser la primera de todos los scripts que realicemos.
La segunda línea de nuestro script, simplemente utiliza el comando para escribir en pantalla
(echo) y escribe la línea Hola Mundo.

Una vez creado el fichero, debemos darle permisos de ejecución, mediante el comando

chmod a+x primero.sh

Posteriormente para ejecutarlo debemos llamarlo como ./permiso.sh (el punto barra es para
indicarle que lo busque en el directorio actual, ya que dicho directorio no estará seguramente
incluido en el PATH del sistema).

Las comillas dobles que hemos usado para escribir Hola Mundo no son necesarias, y podéis
comprobar como quitándolas el proceso se ejecuta exactamente igual. Sin embargo, es una
buena práctica encerrar siempre los textos entre comillas dobles, y en caso de que contengan
caracteres especiales (como el *, el $, etc.), es mejor usar comillas simples, que son más
potentes que las comillas dobles. Prueba lo siguiente:

echo esto es un asterisco * sin comillas


echo esto es un dólar y tres letras $ABC sin comillas
echo “esto es un asterisco * entre comillas dobles”
echo ‘esto es un asterisco * entre comillas simples’
echo “esto es un dólar y tres letras $ABC entre comillas dobles”
echo ‘esto es un dólar y tres letras $ABC entre comillas simples’

Si tenemos que ejecutar varias líneas y queremos escribirlas en una sola, podemos hacerlo
usando el símbolo punto y coma para indicar que lo siguiente es otra línea, aunque este en la
misma:

echo Hola ; pwd ; echo Adios # esto son tres líneas en una sola.
También podemos hacer lo contrario, escribir una sola línea en varias. Para ello usamos el
carácter contrabarra cuando queramos que nuestra línea se “rompa” y continué en la línea de
abajo.

echo esto \
es una sola línea \
aunque ocupe 3 en pantalla. # esto es una línea escrita en tres.

En estos últimos ejemplos mostramos como se pueden usar comentarios en los scripts. Basta
con usar el símbolo almohadilla (#) donde queramos, todo lo que quede a la derecha de dicho
Página 5 Linux. Shell Scripts.
IMPLANTACIÓN DE SISTEMAS OPERATIVOS.CURSO 2012/2013

símbolo es un comentario.
Si usamos # como primer carácter de una línea, toda la línea es de comentario.

USO DE VARIABLES EN LOS SCRIPTS. EXPANSIONES.

Las variables de los shell scripts son muy simples, ya que no tienen tipo definido ni necesitan ser
declaradas antes de poder ser usadas. Para introducir valor en una variable simplemente se usa
su nombre, y para obtener el valor de una variable se le antepone un símbolo dólar.

#!/bin/bash
DECIR=”Hola Mundo”
echo $DECIR

Este script realiza exactamente la misma función que el anterior, pero usando una variable.

Cualquier valor introducido en una variable se considera alfanumérico, así que si realizamos lo
siguiente:

NUMERO=4 # No se debe dejar ningún espacio en la asignación.


echo NUMERO+3

Obtendremos por pantalla la cadena de caracteres 4+3.

$(ORDEN)

En Linux podemos usar varias expansiones en las líneas de comandos, que son especialmente
útiles en los scripts. La primera expansión consiste en usar $( ) . Esta expansión permite
ejecutar lo que se encuentre entre los paréntesis, y devuelve su salida.

echo pwd # escribe por pantalla la palabra pwd


echo $(pwd) # ejecuta la orden pwd, y escribe por pantalla su
resultado.

Así, por ejemplo, la siguiente instrucción copia el fichero /etc/network/interfaces en el


directorio actual con el nombre red290411.conf (suponiendo que estamos en la fecha 29 de
Abril de 2011).

NOMBRE_FICHERO=”red”$(date +%d%m%y)”.conf”
cp /etc/network/interfaces $NOMBRE_FICHERO

Página 6 Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

Como es lógico, es perfectamente posible no usar variables en el ejemplo anterior y hacerlo


todo en una línea, pero es una buena práctica no complicar excesivamente cada una de las
líneas del script.
Esto nos permitirá una modificación mucho más simple y la depuración en caso de que existan
errores suele ser bastante más rápida, al menos mientras nuestro nivel de programación no sea
bastante alto.

El efecto conseguido con $( orden ) se puede conseguir también usando la tilde invertida
`orden`.

$((OPERACIÓN ARITMÉTICA))

Otra expansión que podemos usar es $(( )) (símbolo dólar pero con dos paréntesis). Los dobles
paréntesis podemos sustituirlos si queremos por corchetes. $[ ].

Esta expansión va a tratar como una expresión aritmética lo que esté incluido entre los
paréntesis, va a evaluarla y devolvernos su valor.

NUMERO=4
echo $(($NUMERO+3)) # sería lo mismo poner echo $[$NUMERO+3]

Obtenemos en pantalla el valor 7.

El comando let, que nos permite realizar operaciones aritméticas como la anterior, pero sin
tener que usar expansiones ni dólares para las variables.

NUMERO=4
let SUMA=NUMERO+3
echo $SUMA

Obtenemos el mismo valor 7, y como vemos no hemos usado ni dólar, ni paréntesis.

Los operadores aritméticos que podemos usar para realizar operaciones son:
Resta (-), Suma (+), División (/), Multiplicación (*) y Modulo o Resto (%).

Página 4 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

LET. BC.

Cread con nano un fichero con nombre media.sh con el siguiente contenido:

Para hacer ejecutable media.sh y ejecutadlo. Si lo habéis escrito bien veréis como realmente os da la
media aritmética de las tres notas introducidas.

La línea
MEDIA=$[ $SUMA / 3 ]
Podría haberse escrito también como
let MEDIA=SUMA/3

Si ejecutamos el script, veremos que hay un problema, podéis comprobar como bash no trabaja
con decimales, de modo que, si introducimos por ejemplo 10, 10 y 6 nos dirá que la media es
8, mientras que la media realmente es 8,66.

Podemos obligar a que bash trabaje con decimales utilizando un comando que sirve como
calculadora en Linux, este comando es bc. Este comando admite un gran número de
parámetros, pero en estos apuntes vamos a usarlo simplemente para indicar que queremos
obtener decimales en las operaciones. Para ello simplemente haremos el siguiente cambio..

MEDIA =$[ $SUMA / 3 ]


Lo sustituiremos por
MEDIA=$( echo “scale=4; $SUMA/3” | bc –l )

Vemos cómo debemos generar una salida con echo, el primer campo scale indica cuantos
decimales queremos obtener (4 en este caso), luego y separado por un punto y coma ponemos
la operación aritmética que deseamos realizar, sin necesidad de poner corchetes, dobles
paréntesis o usar let. El resultado de este echo lo enviamos al comando bc –l mediante una
tubería.

Página 5 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

ESTRUCTURAS CONDICIONALES.

IF.

La principal estructura condicional de los scripts en shell es el if (Sí en inglés):

if [ expresión ]; then
Realizar si expresión es verdadera
fi

La expresión es cualquier expresión lógica que produzca un resultado verdadero o falso. Si


estamos operando con cadenas alfanuméricas, los operadores que podemos utilizar son los
siguientes:

Operadores de comparación de cadenas alfanuméricas

Cadena1 Cadena2 Verdadero si Cadena1 es IGUAL a Cadena2


Cadena1 Cadena2 Verdadero si Cadena1 NO es IGUAL a Cadena2
Cadena1 Cadena2 Verdadero si Cadena1 es MENOR a Cadena2
Cadena1 Cadena2 Verdadero si Cadena1 es MAYOR que Cadena2
Verdadero si Cadena1 NO ES NULO (tiene algún valor)
Variable1
Verdadero si Cadena1 ES NULO (está vacía o no está
Variable1
definida)

Los anteriores operadores sólo son válidos para comparar cadenas, si queremos comparar
valores numéricos, hemos de usar los siguientes operadores:

Página 6 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

Operadores de comparación de valores numéricos.

Numero1 -eq Numero2 Verdadero si Numero1 es IGUAL a Numero2.


(equal)
Numero1 -ne Numero2 Verdadero si Numero1 NO es IGUAL a Variable2.
(not equal)

Numero1 -lt Numero2 Verdadero si Numero1 es MENOR a Variable2.


(less that)
Numero1 -gt Numero2 Verdadero si Numero1 es MAYOR que Variable2.
(greater that)
Numero1 -le Numero2 Verdadero si Numero1 es MENOR O IGUAL que
Numero2. (less or equal).

Numero1 -ge Numero2 Verdadero si Numero1 es MAYOR O IGUAL que


Numero2 . (greater or equal).

Si usamos operadores de comparación numéricos con valores de cadena, el sistema nos dará
un error como el siguiente:

Página 7 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

IF..ELSE

La estructura if podemos ampliarla usando la construcción else (en caso contrario) y elif (en
caso contrario si…).

La estructura simple de else es la siguiente:

if [ expresión 1 ]; then
Realizar si expresión 1 es verdadera
else

Realizar si expresión 1 es falsa


fi

IF..ELIF..ELSE

Una estructura con elif (else if) tiene la siguiente forma:

if [ expresión1 ]; then
Realizar si expresión1 es verdadera

elif [ expresión2 ]; then


Realizar si expresión1 es falsa, pero es verdadera expresión2

elif [ expresión3 ]; then


Realizar si exp1 y exp2 son falsas, pero es verdadera expresión3

else
realizar si todas las expresiones anteriores son falsas

fi

Página 8 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

Hay que tener muchísimo cuidado con los espacios en blanco, y seguramente durante nuestros
primeros scripts casi todos los errores vendrán por haberlos usado mal en las estructuras if.

Hay que recordar que los corchetes llevan espacios en blanco tanto a izquierda como derecha,
que el punto y coma sin embargo va pegado al corchete cerrado, y que SIEMPRE hay que poner
espacios en blanco en las expresiones.

Veamos algunos errores muy comunes, para que no los cometáis.

bash: [3: command not found.


If [3 -eq 5 ]; then
Hemos usado [3 en lugar de [ 3
Bash: [: jose: integer expression expected.
if [ “Jose” -eq “Jose” ]; then
Debíamos haber usado =

Esto no nos devolverá error, y parece que funciona,


if [ 3 = 4 ]; then
pero en realidad no es así, hay que usar -eq

Esto devuelve verdadero. Sirva como prueba que no


if [ 3 > 4 ]; then hay que usar operadores de cadena para comparar
números como dijimos anteriormente.
No hemos dejado espacios en la condición =. Esta
expresión da como valor verdadero. Mucho cuidado
If [ jose=Antonio ]; then
con este error, que nos puede volver locos en
depuración.

Otro error muy común es el siguiente:

#!/bin/bash
PROFESOR=”Juana”
if [ $PROFSOR = “Juana” ]; then
echo “Hola Juana”
fi

Este programa nos devuelve por pantalla el siguiente error:


bash: [= unary operador expected

Que traducido resulta, me he encontrado un [ (corchete abierto) y luego un operador (el =) sin
nada en medio, y eso no funciona.

Revisando el programa anterior, vemos como nos hemos equivocado en el nombre de la


variable, por lo cual $PROFSOR no tiene ningún valor (es nula) y por lo tanto al no valer nada,
el programa lo que ve es lo siguiente: if [ = “Juana” ].

Hemos visto operadores aritméticos y operadores para cadena, pero en las expresiones
podemos utilizar cualquier operación que nos devuelva un valor lógico (0 para verdadero). Por
ejemplo, podemos usar la función test del bash, que funciona de la siguiente forma:

Operaciones condicionales usando test.


-a fichero Verdadero si fichero existe
-d fichero Verdadero si fichero existe, y es un fichero de tipo directorio

Página 9 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

-f fichero Verdadero si fichero existe, y es un fichero regular.


-r fichero Verdadero si fichero existe y se puede leer
-w fichero Verdadero si fichero existe y se puede escribir
-x fichero Verdadero si fichero existe y se puede ejecutar
fichero1 -nt fichero2 Verdadero si fichero1 es más nuevo que fichero2
fichero1 -ot fichero2 Verdadero si fichero1 es más viejo que fichero2

Si lo necesitamos, podemos anidar expresiones usando tanto and (y, &&) como or (o, ||).

if [ expresión1 ] && [ expresión2 ]; then


se ejecuta si expresión1 expresión2 son verdaderas
fi

if [ expresión1 ] || [ expresión2 ]; then


se ejecuta si expresión1 expresión2 son verdaderas
fi

También podemos usar el operador not (!) para indicar una negación.

if ! [ expresión1 ]; then
se ejecuta si expresión1 NO es verdadera
fi

Para hacer algunos ejercicios, vamos a aprovechar para explicar mejor cómo le podemos pedir
datos al usuario. Se hace con la orden read y es muy simple de usar:

read -p “texto de la pregunta” variable

La ejecución del script se parará, mostrará por pantalla el texto de la pregunta, y dejará que el
usuario escriba la respuesta, cuando pulse INTRO la respuesta dada se introducirá como valor
de variable.

read también puede ser usada sin el parámetro -p, de la forma read variable. También podemos
hacer que lea un determinado número de caracteres, sin obligar a que el usuario pulse intro,
con el parámetro -n número_de_caracteres. El parámetro -s silencia el eco (no se ve por
pantalla lo que el usuario escribe).

Ahora que sabemos usar el read, hagamos por ejemplo un programa que nos permita indicar si
un número introducido es par o impar.

#!/bin/bash
# parimpar.sh - script que nos pide un número e indica si es par o impar.
clear
read -p “Introduzca un número: “ NUMERO
let RESTO=NUMERO%2
if [ $RESTO -eq 0 ]; then
echo “El número $NUMERO es par”
else
echo “El número $NUMERO es impar”
fi

Página 10 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

Hagamos un script un poco más complicado… vamos a pedir al usuario un número de 3 cifras y
vamos a indicar si es capicúa.

#!/bin/bash
# capicua.sh - script que nos pide un número de tres cifras e indica si es
# capicúa o no.
clear
read -n 3 -p “Número entre 100 y 999 (no pulses INTRO) : “ NUMERO
echo # este echo sirve para introducir un retorno de línea
if [ $NUMERO -lt 100 ]; then
echo “Lo siento, has introducido un número menor de 100”
else
PRIMERA_CIFRA=$(echo $NUMERO | cut -c 1)
TERCERA_CIFRA=$(echo $NUMERO | cut -c 3)
if [ $PRIMERA_CIFRA = $TERCERA_CIFRA ]; then
echo “El número $NUMERO es capicúa.”
else
echo “El número $NUMERO ni es capicúa ni ná”.
fi
fi

Es evidente que podíamos haber hecho este último script mucho más corto, por ejemplo
usando una línea como:

if [ $(echo $NUMERO | cut -c 1) = $(echo $NUMERO | cut -c 3) ]; then

Pero eso ya queda al gusto de cada programador.

Cuando hacemos un script de varias líneas como el anterior, es posible que cometamos algún
fallo. Una opción que podemos usar para depurar los scripts y encontrar rápidamente los
errores, es añadir un -x en la llamada al bash de la primera línea. Esto hará que cada línea antes
de ejecutarse sea mostrada por pantalla tal y como la está interpretando el bash.

#!/bin/bash -x

Para que esto funcione, es necesario que hagamos el script ejecutable, no es válido si
lanzamos el script con la orden source o con el punto. Hay que ejecutar el script haciéndolo
antes ejecutable con chmod y luego ejecutándolo con ./script.

CASE.

Hemos visto la principal estructura condicional que es el if, pero tenemos alguna otra a nuestra
disposición, como el case. Esta estructura nos permite ejecutar varias acciones, dependiendo del
valor de una variable o expresión.

Página 11 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

case VARIABLE in
valor1)
se ejecuta si VARIABLE tiene el valor1;;
valor2)
se ejecuta si VARIABLE tiene el valor2;;

*)Se ejecuta si VARIABLE tiene otro valor distinto;;

Esac

Veamos un ejemplo de utilización del case.

En el case, no solo podemos preguntar por valores directos, sino que también podemos utilizar
los comodines que vimos anteriormente. Veamos un par de ejemplos de case utilizado junto con
comodines.

Página 12 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

ESTRUCTURAS ITERATIVAS. (BUCLES).

Las principales estructuras iterativas que podemos usar en shell scripts son for, while, until y
select.

FOR.

La estructura básica de for es la siguiente:

for VARIABLE in conjunto; do


Estas líneas se repiten una vez por cada elemento del conjunto,
Y variable va tomando los valores del conjunto uno por uno.
done

Ese conjunto que aparece en la estructura del for, es normalmente un conjunto de valores
cualesquiera, separados por espacios en blanco o retornos de línea. Así, si queremos mostrar
los días de la semana por pantalla podríamos hacerlo mediante este script:

Así, por ejemplo, si queremos obtener por pantalla los números del 1 al 10 podríamos hacerlo
de la siguiente forma:

Página 13 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

La potencia del comando for viene de la flexibilidad de valores que admite el conjunto de
valores, ya que podemos crear dicho conjunto con una orden del sistema operativo. En el
siguiente ejemplo vamos a usar como conjunto los nombres de los ficheros con extensión sh
del directorio actual:

El conjunto puede ser cualquier salida de cualquier orden, y formara elementos utilizando el
espacio en blanco como separador de elementos. Fijaros en el siguiente ejemplo:

Vemos como utilizamos como conjunto el contenido de un fichero. Vemos también como la
línea “jose antonio” la divide en 2 elementos distintos debido al espacio en blanco.

Existe una orden en GNU/Linux que nos permite obtener una secuencia de números como
salida de la orden, esta orden es seq.

seq último-número
seq primer-número último-número
seq primer-número incremento último-número

Modifiquemos el ejercicio de mostrar los números del 1 al 10 que hicimos anteriormente,


usando esta vez la orden seq.

Página 14 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

Vamos a realizar un ejemplo algo más complejo utilizando for y seq. Vamos a crear un script
llamado suma100.sh que nos va a decir por pantalla cuanto suman todos los números del 1 al
100, es decir, 1+2+3+4+5…+100.

Modifica el anterior ejercicio para que el script sume todos los números pero no entre 1 y 100,
sino entre dos números que pida el script por pantalla.

Desde la versión de bash 3.0 se introdujo un cambio en el for que permite utilizar directamente
rangos sin tener que usar la orden seq. Si estamos seguros de que contamos con un bash
moderno podemos utilizar la siguiente característica del for:

Desde la versión de bash 4.0 se introdujo otro cambio, que permite utilizar también incrementos
en los rangos, de la siguiente manera:

Como vemos, podemos utilizar los rangos de la siguiente forma:

{INICIO..FINAL}
{INICIO..FINAL..INCREMENTO}

Si nuestro bash es de un sistema relativamente moderno, podemos usar estos rangos sin ningún
tipo de problemas, que tienen la ventaja adicional de ser algo más rápidos que la orden seq.

Si no estamos seguros de los sistemas sobre los que se ejecutara nuestro script podemos usar
el seq para conseguir una mayor compatibilidad, aunque hoy en día es muy difícil encontrar en
ningún sistema un bash inferior al 4.0.

El for de bash también permite utilizar el formato basado en trio de expresiones común al
lenguaje C.

for (( expresión-inicio; condición-para-seguir; expresión-de-paso ))

Página 15 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

Normalmente utilizaremos este formato de la siguiente forma:

for (( VARIABLE=inicio; condición-para-seguir; incrementamos ))

Veamos un ejemplo, con un script que como salida nos muestra los números pares entre 2 y
40.

Podemos crear un bucle infinito de la siguiente forma:

Podemos utilizar la instrucción break para salirnos inmediatamente de un bucle for. Fijaros en
el siguiente ejemplo:

Este tipo de elementos (bucles infinitos, break, etc.) se consideran como “poco elegantes”
desde el punto de vista de la programación y es mejor acostumbrarse a no usarlos, ya que
existen otro tipo de alternativas más refinadas. Sin embargo son herramientas potentes y es
conveniente conocerlas.

Imaginemos que queremos copiar a un llaverito USB (montado en /media/usbdisk por ejemplo)
todos los scripts que tengamos en nuestro directorio home, sin importar en que directorio estén,
podríamos hacerlo fácilmente con este script:

#!/bin/bash
for programa in $( find ~ -iname “*sh” 2> /dev/null ); do
echo “copiando el script :” $programa
cp $programa /media/usbdisk
done

Página 16 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

Ya que estamos, mejoremos el script anterior para que cree un directorio scripts en nuestro
llaverito, pero únicamente si no existe.

#!/bin/bash
if ! [ -d /media/usbdisk/scripts ]; then
mkdir /media/usbdisk/scripts
fi
for programa in $( find ~ -iname “*sh” 2> /dev/null ); do
echo “copiando el script :” $programa
cp $programa /media/usbdisk
done

WHILE Y UNTIL

Cuando no queremos recorrer un conjunto de valores, sino repetir algo mientras se cumpla una
condición, o hasta que se cumpla una condición, podemos usar las estructuras while y until.

La estructura del while es la siguiente:

while [ expresión ]; do
estas líneas se repiten MIENTRAS la expresión sea verdadera
done

La estructura del until es la siguiente:

until [ expresión ]; do
estas líneas se repiten HASTA que la expresión sea verdadera
done

Ambas estructuras, tanto while como until realmente realizan exactamente lo mismo, al
efectuar la comprobación de la expresión en la primera línea, no como en otros lenguajes.

Veamos un ejemplo de un script usando la estructura while (mientras).

#!/bin/bash
#doble.sh - script que pide números y muestra el doble de dichos números.
# el script continua ejecutándose mientras que no se introduzca 0.
read -p “Dime un número (0 para salir) : “ NUMERO
while [ $NUMERO -ne 0 ]; do
echo “El doble de $NUMERO es :” $(($NUMERO*2))
read -p “Dime un número (0 para salir) : “ NUMERO
done

Página 17 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

Ahora veamos cómo queda el script, usando la estructura until (hasta).

#!/bin/bash
#doble.sh - script que pide números y muestra el doble de dichos números.
# el script continua ejecutándose mientras que no se introduzca 0.
read -p “Dime un número (0 para salir) : “ NUMERO
until [ $NUMERO -eq 0 ]; do
echo “El doble de $NUMERO es :” $(($NUMERO*2))
read -p “Dime un número (0 para salir) : “ NUMERO
done

Otro ejemplo, vamos a mostrar por pantalla los número del 1 al 20

#!/bin/bash
NUMERO=1
until [ $NUMERO -gt 20 ]; do
echo “Número vale :” $NUMERO
let NUMERO=NUMERO+1
done

Página 18 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

SELECT

La última estructura iterativa que vamos a ver es select. Esta nos permite realizar una iteración
o bucle, pero presentando un menú por pantalla para que el usuario escoja una opción. Su
estructura general es la siguiente:

select VARIABLE in conjunto opciones; do


Aquí variable toma el valor de una de las opciones del conjunto
done

Esta estructura como vemos es muy parecida a la del for, pero presenta la principal diferencia
en que por definición se crea un bucle sin final, no hay un valor inicial y un valor límite, el bucle
se repetirá eternamente, lo que nos obliga a salirnos del mismo por las bravas, bien con break
que nos permite salirnos del bucle o con exit que nos permite salirnos del script entero.

Veamos un ejemplo:

Al ejecutar el script por pantalla nos presentará un menú automáticamente formado por el
conjunto de opciones que hemos puesto en el select.

Y automáticamente el script realizará un read, pidiendo que el usuario introduzca un valor. El


valor debe ser uno de los números otorgados a las opciones (1.4 en nuestro caso). Aunque el
valor que introduzcamos es un número, dentro del script podéis comprobad como la variable
del select no toma este valor numérico, sino el texto de la opción.

Página 19 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

Podemos comprobar como el bucle es infinito, y la única forma de salir es usando la opción Salir
que en el script ejecuta un break.

Al igual que sucedía con el for, es perfectamente posible crear el conjunto mediante una
instrucción. Así por ejemplo, la instrucción ls nos devuelve un conjunto formado por todos los
ficheros del directorio actual. Vamos a trabajar sobre esta idea:

#!/bin/bash
select FICHERO in $( ls ); do
echo Has seleccionado el fichero $FICHERO
# Ahora podríamos borrarlo, copiarlo, visualizarlo, etc.
Done

Si ejecutáis ese script, veréis dos cosas: Como el conjunto está formado por todos los ficheros
del directorio actual, y como es imposible detener la ejecución del script, como no sea matando
el proceso en primer plano con Control + C

Por cierto, si en el conjunto ponemos directamente el símbolo asterisco ( * ) veremos que tiene
la misma función que un ls, devuelve el listado de ficheros del directorio actual.

select FICHERO in *; do

Hagamos otro ejemplo sobre el select, un poco más avanzado. Vamos a mostrar por pantalla
un menú con todos los mp3 que existan en el directorio home del usuario actual, y vamos a
dejar que escoja uno de ellos para reproducirlo. (Para ello uso un reproductor de mp3 desde
línea de comandos podemos usar la orden mpg321, si no la tenéis instalado lo podéis instalar
con un apt-get install mpg321).

#!/bin/bash
clear
select MP3 in $( find . -iname "*mp3" ); do
echo "Voy a reproducir el mp3 : " $MP3
mpg321 $MP3 &> /dev/null
done

Página 20 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

Volvemos a tener el problema de que la ejecución no se acabará nunca, a menos que la


interrumpamos mediante control c. Vamos a arreglarlo forzando la opción Salir en el conjunto:

#!/bin/bash
clear
CONJUNTO=$(find . -iname "*mp3")
CONJUNTO=$CONJUNTO" Salir"
select MP3 in $CONJUNTO; do
if [ $MP3 = "Salir" ]; then
break
fi
echo "Voy a reproducir el mp3 : " $MP3
mpg321 $MP3 &> /dev/null
done

Como siempre en Informática, este script tan sencillo se puede complicar hasta lo inimaginable.

Por ejemplo, este script necesita para funcionar que los nombres de los archivos mp3 no
contengan espacios en blanco, ya que el conjunto separa sus valores por este carácter. Así, si
tuviéramos una canción con nombre La Gasolina, veríamos que en el menú nos aparecen dos
opciones 1) La y 2) Gasolina, por lo que el script como es obvio no funcionará. ¿Se os ocurre
alguna manera de solucionarlo?

Página 21 . Linux. Shell Scripts.


IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

PASO DE PARÁMETROS A UN SCRIPT.

Podemos pasar parámetros tanto a los scripts como a las funciones. Los parámetros en bash se
indican como un símbolo dólar ($) seguido de un número o carácter. Los principales parámetros
que se pueden usar son:

Parámetros
$1 Devuelve el 1º parámetro pasado al script o función al ser llamado.
$2 Devuelve el 2º parámetro.
$3 Devuelve el 3º parámetro. (Podemos usar hasta $9).
$* Devuelve todos los parámetros separados por espacio.
$# Devuelve el número de parámetros que se han pasado.
$0 Devuelve el parámetro 0, es decir, el nombre del script o de la función.

script01.sh juan 12 45

$0 $1 $2 $3

$* = juan 12 45
$# = 3

Para comprobar lo anterior, cread un script como el siguiente:

#!/bin/bash
# parámetros.sh - script sobre parámetros.
echo “El primer parámetro que se ha pasado es “ $1
echo “El tercer parámetro que se ha pasado es “ $3
echo “El conjunto de todos los parámetros : “ $*
echo “Me has pasado un total de “ $# “ parámetros”
echo “El parámetro 0 es : “ $0

Si hacemos este script ejecutable, y lo llamamos como:

./parámetros.sh Caballo Perro 675 Nueva York

Obtendríamos por pantalla lo siguiente:

El primer parámetro que se ha pasado es Caballo


El tercer parámetro que se ha pasado es 675
El conjunto de todos los parámetros: Caballo Perro 675 Nueva York
Me has pasado un total de 5 parámetros
El parámetro 0 es: ./parámetros.sh
Página 22 . Linux. Shell Scripts.
IMPLANTACIÓN DE SISTEMAS OPERATIVOS.

VALORES DEVUELTOS POR LAS ÓRDENES.

¿Existe un parámetro especial, el $? que nos devuelve el valor del resultado de la última orden.

Es decir, después de ejecutar cualquier orden o comando del sistema (o casi cualquier orden
mejor dicho) podemos comprobar el valor de $? que tendrá un 0 si todo ha ido bien, y otro
valor cualquiera en caso de que haya fallado. Comprobarlo es muy simple:

Desde la línea de comandos, haced un cd a un directorio que no existe, por ejemplo

cd /juegos/faluyah

y luego mirad el contenido de $? con un

echo $?

¿Comprobareis como $? vale 1, es decir, indica que la última orden no funcionó correctamente.

Ahora haced un cd a un directorio que si exista

cd /etc/network

y luego mirad el contenido de $? con un

echo $?

Comprobareis como vale 0, es decir, indica que la última orden funciono sin problemas.
Este parámetro puede sernos muy útil realizando scripts, ya que nos permite una forma rápida
y cómoda de ver si todo está funcionando bien o no.

Como ejemplo, realizad un script con nombre borrar.sh. Dicho script aceptará como parámetro
el nombre de un fichero. El script debe eliminar ese fichero, pero antes debe guardar una copia
de seguridad del mismo en el directorio papelera que debemos crear en nuestro home de
usuario. Una vez comprobado que funciona, pasadle como parámetro el nombre de un fichero
que el usuario no tenga permisos para borrar (recordad que además debe estar en un directorio
en el que el usuario no tenga el permiso de escritura). ¿Como es obvio, el script nos dará un
error al intentar borrar dicho fichero, pues precisamente después de ese rm es donde podemos
colocar un if preguntando por $?, de modo que interceptemos el error y avisemos al usuario de
que dicho fichero no ha podido ser borrado.

Página 23 . Linux. Shell Scripts.

También podría gustarte

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy