Shell Scripts INICIAL
Shell Scripts INICIAL
EL SHELL BASH
shell
Sistema Linux usuario
− Bourne shell o sh: es el primer shell escrito para Unix por Steve Bourne. Hoy
obsoleto, muchos intérpretes de comandos recientes conservan la
compatibilidad con él. El programa correspondiente es sh o bsh.
− Korn Shell o KSH: es uno de los intérpretes de comandos más utilizados en el
mundo Unix. Es compatible con el shell Bourne original. Existe una
implementación libre de éste: el “Public Domain KSH”. El binario
correspondiente en Linux es pdksh.
− C shell: este shell fue desarrollado por la rama BSD de Unix y usa una sintaxis
diferente a los anteriores. Puede lanzarse mediante el programa csh.
− tcsh: es una implementación mejorada del C shell que dispone de una edición
avanzada de la línea de comandos. Su ejecutable es tcsh.
− Bash o Bourne Again Shell: como su nombre indica, es una nueva
implementación del shell Bourne y se parece mucho al Korn shell. Muy
funcional, es el intérprete de comandos predeterminado en Linux que se
detalla en el resto del tema. El programa correspondiente es bash.
VARIABLES
Manipulación de variables
Nombrado
Asignación
Una variable llamada var puede recibir un valor por una asignación de la forma
var=valor.
Una variable existe desde que se le asigna un valor; este valor puede ser un nº, un
carácter, una palabra o una cadena de caracteres con cualquier carácter especial:
Ej:
Si no se proporciona ningún valor, la variable recibe una cadena vacía; las dos
sintaxis siguientes son equivalentes:
var5=”” var6=
Llamada y visualización
[alumno]> var7=registro
[alumno]> echo contenido de la variable var7: $var7
contenido de la variable var7: registro
[alumno]> echo el archivo es: $var7_2006.txt
el archivo es:
[alumno]> echo el archivo es: ${var7}_2006.txt
el archivo es: registro_2006.txt
El comando set llamado sin argumentos muestra la lista completa de las variables
definidas en el shell actual.
[alumno]> x=3
[alumno]> echo $x
3
[alumno]> bash
[alumno]> echo $x
[alumno]> x=7
[alumno]> echo $x
Shell Scripts Página 3 de 32
Sistemas Operativos Monousuario y Multiusuario 1º ESI
7
[alumno]> exit
[alumno]> echo $x
3
Borrado
Una vez que una variable existe, solo puede destruirse utilizando el comando
unset. Por ejemplo: unset var2.
Variables de Entorno
o emacs.
$HOME: Ruta completa del directorio personal del usuario conectado
actualmente.
$IGNOREEOF: Indica el nº de veces que el shell ignorará el carácter de fin de
archivo (EOF) pasado mediante las teclas [Ctrl]+[d] antes de terminar.
$OLDPWD: Directorio donde se encontraba anteriormente el usuario. Esta
variable la usa el comando cd -.
$PATH: Lista de directorios separados por el carácter : (dos puntos) con los
ejecutables del sistema (binarios, scripts shell). Cuando se da un comando,
el shell busca automáticamente los ejecutables en los directorios listados en
esta variable, por orden de lista.
Para agregar un directorio a esta lista, se usa la sintaxis siguiente:
PATH=$PATH:/nuevo_directorio
CARACTERES GENÉRICOS
CARACTERES DE CITA
Las comillas: “
Como ocurre con los apóstrofes, todos los caracteres especiales entre comillas se
ignoran, exceptuando $, ` (acento abierto) y \. Por ejemplo:
La barra invertida: \
El uso de los caracteres de cita permite manipulas archivos con nombres poco
convencionales. Una vez creados hay que usarlos con mucha prudencia,
especialmente a la hora de borrar:
Por último, estos caracteres cita inhiben el significado de la tecla [Intro] que
caracteriza el fin del comando; por ello se obtiene la presentación del prompt
secundario $PS2 cuando falta una comilla o un apóstrofe de cierre, o bien cuando
se coloca una barra invertida al final de la línea:
ALIAS
Ciertas líneas de comandos pueden alargarse rápidamente sobre todo con el uso
de tuberías y redirecciones, por lo que su uso frecuente puede resultar
desagradable. Pero es posible simplificar el trabajo del usuario definiendo alias de
comandos.
Por ejemplo:
Es posible suprimir todos los alias con la opción -a del comando unalias.
EJECUCIÓN DE COMANDOS
Los comandos escritos por los usuarios pueden ser de naturaleza diferente:
− alias;
− comando interno;
− comando externo.
., alias, bg, bind, break, builtin, case, cd, command, continue, declare, dirs,
disown, echo, enable, eval, exec, exit, export, fc, fg, for, getopts, hash, help,
history, if, jobs, kill, let, local, logout, popd, pushd, pwd, read, readonly, return,
set, shift, shopt, source, suspend, test, times, trap, type, typeset, ulimit, umask,
unalias, unset, until, wait, while.
Shell Scripts Página 8 de 32
Sistemas Operativos Monousuario y Multiusuario 1º ESI
La página del manual man Bash detalla los comandos internos que se estudian
aquí.
Comandos externos
type, whereis
SUSTITUCIÓN DE COMANDOS
Por ejemplo:
echo “mi login es `whoami`”
Por ejemplo:
echo “contenido de mi directorio: $(ls /home/$whoami))”
• Crear un archivo de texto con un editor (vi, emacs, etc.). Este archivo
contendrá las órdenes que el shell va a ir interpretando y ejecutando.
• Asignar permisos de ejecución al archivo creado, utilizando la orden
chmod.
• Ejecutar el script generado pasándole los parámetros necesarios
./shell_script param1 param2 …
bash prog.sh
Consiste en lanzar un nuevo bash con el nombre del script como argumento. De ello
resulta la creación de subproceso bash que termina automáticamente al finalizar la
ejecución de script. Cualquier modificación del entorno solo interviene en el
subshell, no se modifica la shell inicial.
./prog.sh
Esta forma también utiliza una subshell para su ejecución. El resultado de la
ejecución es el mismo que en la sintaxis anterior.
. prog.sh
El comando interno del shell . (punto, similar al comando interno source) indica al
bash actual que interprete las instrucciones contenidas en el archivo pasado como
argumento. En este caso el entorno Shell de conexión se modifica según el código
del script que ejecuta.
exec ./prog.sh
En este caso es el Shell actual el que ejecuta las instrucciones contenidas en el
archivo.
RECOMENDACIONES:
Ejemplo1:
#!/bin/bash
echo El nombre del programa es $0
echo El primer parámetro recibido es $1
echo El segundo parámetro recibido es $2
echo El tercer parámetro recibido es $3
echo El cuarto parámetro recibido es $4
Ejemplo2:
#!/bin/bash
echo El nombre del programa es $0
echo El número total de parámetros es $#
echo Todos los parámetros recibidos son $*
echo El primer parámetro recibido es $1
echo El segundo parámetro recibido es $2
echo El tercer parámetro recibido es $3
echo El cuarto parámetro recibido es $4
shift
Sintaxis: shift n
Esta orden se utiliza para desplazar los argumentos, de manera que $2 pasa a ser
$1, $3 pasa a ser $2, y así sucesivamente (esto si el desplazamiento n es igual a
1). Es muy utilizada dentro de los bucles.
Ejemplo3:
#!/bin/bash
#Este script se llama ej_shift2
read
Ejemplo4:
#!/bin/bash
#script ej_read
#La opción –n se emplea para evitar el retorno de carro
echo –n “Introduce una variable: “
read var
echo La variable introducida es: $var
Ejemplo5:
#!/bin/bash
#script ej_read_var que lee varias variables con read
echo –n “Introduce las variables: “
read var1 var2 var3
echo Las variables introducidas son:
echo var1 = $var1
echo var2 = $var2
echo var3 = $var3
$./ej_read_var
Introduce las variables: uno dos
Las variables introducidas son:
var1 = uno
var2 = dos
var3 =
$
expr
Operadores aritméticos
Operadores relacionales
Estos operadores se utilizan para comparar dos argumentos. Los argumentos
pueden ser también palabras. Si el resultado de la comparación es cierto, el
resultado es uno (1); si es falso, el resultado es cero (0). Estos operadores se
utilizan mucho para comparar operandos y tomar decisiones en función de los
Shell Scripts Página 14 de 32
Sistemas Operativos Monousuario y Multiusuario 1º ESI
Los símbolos > y < tienen significado especial para el shell, por lo que deben ser
entrecomillados.
Ejemplo7:
#!/bin/bash
#El script se llama ejemplo7
#script que determina si dos variables leídas desde teclado son iguales o no
echo “¿Son iguales las variables?”
echo “--------------------------“
echo –n “Introduce la primera variable: “
read var1
echo –n “Introduce la segunda variable: “
read var2
resultado=`expr $var1 = $var2`
echo Resultado=$resultado
Operadores lógicos
& And lógico. Si arg1 y arg2 son distintos de cero, el resultado es arg1;
si no es así, el resultado es arg2.
: El arg2 es el patrón buscado en arg1. Si el patrón arg2 está encerrado
dentro de paréntesis \( \), el resultado es la parte de arg1 que
coincide con arg2. Si no es así, el resultado es simplemente el número
de caracteres que coinciden.
Otros ejemplos:
expr 4 + 5 devuelve 9
expr 3\* 4 + 6 \/ 2 devuelve 15
expr 3 \* \( 4 + 3 \) \/2 devuelve 10
echo `expr 6 \< 10` devuelve 1, cierto
echo `expr 6 \> 10` devuelve 0, falso
echo `expr abc \< abd` devuelve 1, cierto
let
Como para el comando test, let puede llamarse de dos maneras: let expresión o
((expresión)). Además, es posible especificar varias expresiones por una coma en
una misma llamada al comando.
Operadores aritméticos
+ suma
- resta
* multiplicación
/ división entera
% resto de la división entera o módulo
** potencia
= asignación
Ejemplos:
let var=2+3
echo $var
Shell Scripts Página 17 de 32
Sistemas Operativos Monousuario y Multiusuario 1º ESI
(( var = 2** 3 ))
echo $var
8
echo $((9/4))
2
Operadores lógicos
&& y lógico
|| o lógico
! negación lógica
< estrictamente menor
<= menor o igual
> estrictamente mayor
>= mayor o igual
== igual
!= diferente
Var++, var--, ++var, --var postincremento, postdecremento,
preincremento y predecremento.
[alumno]> (( i=0 ))
[alumno]> (( i++ >2 )); echo “código de retorno: $? – variable i: $i”
Código de retorno: 1 – variable i: 1
[alumno]> (( i++ > 2 )); echo código de retorno $? – variable i: $i”
Código de retorno: 1 – variable i: 2
[alumno]> (( i++ > 2 )); echo código de retorno $? – variable i: $i”
Código de retorno: 1 – variable i: 3
[alumno]> (( i++ > 2 )); echo código de retorno $? – variable i: $i”
Shell Scripts Página 18 de 32
Sistemas Operativos Monousuario y Multiusuario 1º ESI
La orden test se usa para evaluar expresiones y genera un valor de retorno; este
valor no se escribe en la salida estándar, pero asigna 0 al código de retorno si la
expresión se evalúa como true, y le asigna 1 si la expresión se evalúa como false.
Cuando se invoque la orden test mediante la segunda sintaxis, hay que dejar un
espacio en blanco entre los corchetes.
La orden test puede evaluar tres tipos de elementos: archivos, cadenas y números.
Opciones:
-f Devuelve verdadero (0) si el archivo existe y es un archivo regular (no
es un directorio ni un archivo de dispositivo).
-s Devuelve verdadero (0) si el archivo existe y tiene un tamaño mayor
que cero.
-r Devuelve verdadero (0) si el archivo existe y tiene un permiso de
lectura.
-w Devuelve verdadero (0) si el archivo existe y tiene un permiso de
escritura.
-x Devuelve verdadero (0) si el archivo existe y tiene un permiso de
ejecución.
-d Devuelve verdadero (0) si el archivo existe y es un directorio.
Ejemplo11:
$test –f archivo32
$echo $?
1 (El archivo archivo32 no existe)
$
$ test –f /etc/passwd
$echo $?
0 (El archivo /etc/passwd sí existe)
$
En evaluaciones numéricas, esta orden es sólo válida con números enteros. Los
operadores usados para comparar números son diferentes de los usados para
comparar cadenas. Estos operadores son:
-lt Menor que
-le Menor o igual que
-gt Mayor que
-ge Mayor o igual que
-eq Igual a
-ne No igual a
Hay unos cuantos operadores que son válidos en una expresión de la orden test a
la hora de evaluar tanto archivos como cadenas o números. Estos operadores son
llamados conectores y son:
-o OR
-a AND
! NOT
Ejecución condicional
ESTRUCTURAS CONDICIONALES
Las estructuras de control permiten ejecutar uno o más comandos según el
resultado de una expresión.
La instrucción if
if condición
then
serie de comandos si condición verdaderos
else
serie de comandos si condición falsa
fi
Cada palabra clave de la estructura (if, then, else y fi) debe encontrarse en una
línea distinta pero la cláusula “else” no es obligatoria.
Ejemplo:
#!/bin/bash
Shell Scripts Página 21 de 32
Sistemas Operativos Monousuario y Multiusuario 1º ESI
if [ “$1” = “glop” ]
then
echo “está bien”
else
echo “no está bien”
fi
La instrucción for
El bucle for ejecuta la misma serie de comandos tantas veces como valores haya
en una lista dada; en cada iteración, una variable contiene el valor considerado en
esta lista.
Su sintaxis es:
Ejemplo:
#!/bin/bash
for var in a b c d 1 5 4
do
echo “\$var=$var”
done
echo fin
[alumno]> ./prog.sh
$var=a
$var=b
$var=c
$var=d
$var=1
$var=5
$var=4
fin
La instrucción while
while condición
do
serie de comandos
done
Ejemplo:
#!/bin/bash
((i=0))
while (( i++ < 10 ))
do
echo “\$i=$i”
done
echo fin
[alumno]> ./prog.sh
$i=1
$i=2
$i=3
$i=4
$i=5
$i=6
$i=7
$i=8
$i=9
$i=10
fin
La instrucción case
case $variable in
valor1) accion1;;
valor2) accion2;;
………………….
valorn) accionn;;
*) instrucción nnn;….;;
esac
Ejemplo:
#!/bin/bash
echo “1.- Visualizar nombre de usuario”
echo “2.- Visualizar directorio de trabajo”
echo “Introducir la opción deseada \c”; read opción
case opción in
1) echo “el nombre de usuario es $LOGNAME”;;
2) echo “el directorio de trabajo es $HOME”;;
*) echo “no has tecleado ni 1 ni 2”;;
esac
La instrucción until
until condición
do
serie de acciones
done
La instrucción continue
Provoca un salto al comienzo del bucle para continuar con la siguiente iteración.
Vuelve a ejecutar las órdenes que forman la condición del bucle. Si viene seguido
de un nº n, saldrá de n niveles. Se puede usar en cualquiera de los bucles que
hemos visto (while, until y for).
La instrucción break
La instrucción exit
EJEMPLOS
#!/bin/bash
#misdatos.sh
#muestra datos relativos al usuario que lo invoca
echo “MIS DATOS.”
echo “Nombre: “$LOGNAME
echo “Directorio: “ $HOME
echo –n “Fecha: “
date
#fin de misdatos.sh
#!/bin/bash
#ciertofalso.sh: escribe cierto o falso según parámetro numérico
if [ $1 = “0” ]
then
echo “Cierto. El parámetro es 0”
else
echo “Falso. El parámetro no es 0”
fi
#!/bin/bash
#nvoarch.sh: recibe un nombre y crea un archivo con ese nombre.
#si ya existe emite un mensaje
if [ -f $1 ]
then
echo El archivo ya existe
else
touch $1
echo El archivo $1 fue creado
fi
#!/bin/bash
#rwsi.sh: Indica si un archivo tiene permiso de lectura / escritura
ARCH=$1
if [ -r $ARCH –a –w $ARCH ] # -a similar a AND y –o similar a OR
then
echo El archivo $ARCH se puede leer y escribir
else
echo Al archivo $ARCH le falta algún permiso
fi
ls –l $ARCH
#!/bin/bash
#yo.sh: Captura datos del usuario
clear
echo “Datos del usuario.”
echo –n “Nombre y Apellido: ”; read NOMBRE
echo –n “DNI: “; read DNI
echo
echo “Ha ingresado los siguientes datos: “
echo “Nombre y Apellido: $NOMBRE”
echo “Dni: $DNI”
echo –n “¿es correcto? (sN): “; read RESP
if [ “$RESP” = “s” –o “$RESP” = “S” ]
then
echo “Fin de ingreso.”
else
echo “Debe ingresar sus datos nuevamente”
fi
#!/bin/bash
#ecopars.sh: Muestra los parámetros recibidos
echo Cantidad de parámetros: $#
for VAR in $*
do
echo $VAR
done
#!/bin/bash
#mostrar.sh: Se invoca con 3 parámetros y los muestra
echo Nombre del programa: $0
echo Parámetros recibidos:
echo $1; echo $2; echo $3
echo
#!/bin/bash
#trabajo.sh. Dice si se trabaja según el día de la semana
#Invocar con parámetros: domingo, feria, u otro nombre cualquiera
if [ $1 = “domingo” ]
then
echo “no se trabaja”
elif [ $1 = “feriado” ]
then
echo “en algunos se trabaja”
else
echo “se trabaja”
fi
#!/bin/bash
#listapal.sh: Lista de palabras. Muestra palabras de una lista interna
LISTA=”silla mesa banco cuadro armario”
for I in $LISTA
do
echo $I
done
#fin de listapal.sh
#!/bin/bash
#contarch.sh: muestra nombres y cuanta archivos en el directorio actual
CUENTA=0
for ARCH in *
do
echo $ARCH
CUENTA=`expr $CUENTA + 1` #agrega 1 a CUENTA
done
echo Hay $CUENTA archivos en el directorio `pwd`
#fin de contarch.sh
#!/bin/bash
#diasemana.sh: Nombre de los días de la semana. Invocar con el nº del 0 al 6. 0 es domingo.
case $1 in
0) echo Domingo;;
1) echo Lunes;;
2) echo Martes;;
3) echo Miércoles;;
4) echo Jueves;;
5) echo Viernes;;
6) echo Sábado;;
*) Debe indicar un nº del 0 al 6;;
esac
#!/bin/bash
#estacion.sh: Indica la estación del año aproximada según el mes
case $1 in
diciembre | enero | febrero)
echo Invierno;;
marzo | abril | mayo)
echo Primavera;;
junio | julio | agosto)
echo Verano;;
septiembre | octubre | noviembre)
echo Otoño;;
*) echo estación.sh debe invocarse como
echo estacion.sh mes
echo con el nombre del mes en minúscula;;
esac
#!/bin/bash
#crear1.sh: Crea archivos arch1…arch9, los lista y luego los borra
VAL=1
while [ $VAL –lt 10 ] #mientras VAL sea menor que 10
do
echo creando archivo$VAL
touch arch$VAL
VAL= `expr $VAL + 1`
done
ls –l arch[0-9]
rm arch[0-9]
#fin crearr1.sh
#!/bin/bash
#crear2.sh: Crea archivos arch1…arch9, los lista y luego los borra
VAL=1
until [ $VAL –eq 10 ] #hasta que VAL sea igual que 10
do
echo creando archivo$VAL
touch arch$VAL
VAL= `expr $VAL + 1`
done
ls –l arch[0-9]
rm arch[0-9]
#fin crearr1.sh
#!/bin/bash
#exitar.sh: prueba valores de retorno de exit
#
clear
echo “Pruebas de valores de retorno”
echo “ Invocar con parámetros”
echo “ bien, error1, error2, cualquier cosa o nada”
echo “Verificar valor de retorno con”
echo ‘ echo $?’
echo
VALOR=$1
case $VALOR in
bien)
echo” ->Terminación sin error.”
exit 0;;
error1)
echo “ ->Terminación con error 1.”; exit 1;;
error2)
echo “ ->Terminación con error 2.”; exit 2;;
*)
echo “ ->Terminación con error 3.”
echo “ invocado con parámetro no previsto o sin parámetro.”
exit 3;;
esac
for numero in 1 2 3 4 5
do
echo “1.- Visualizar nombre de usuario”
echo “2.- Visualizar directorio de trabajo”
echo “Introducir la opción deseada \c”;
read opción
case opción in
1) echo “el nombre e usuario es $LOGNAME”;;
2) echo “el directorio de trabajo es $HOME”;;
*) echo “no has introducido ni 1 ni 2”;;
esac
echo “Deseas continuar (S/N) \c”;
read respuesta
done