LA PROGRAMACION SHELL :
Guiones del SHELL
La palabra SHELL hace referencia a dos cosas, intérprete de comandos, y lenguaje de programación.
El lenguaje SHELL es un lenguaje de programación de alto nivel que permite generar ordenes de UNIX controlando el flujo a través de esas ordenes.
El SHELL solo controla el flujo a través de estas ordenes UNIX.
Los guiones del SHELL se utilizan para hacer referencia a un conjunto de ordenes que se ejecuten de la misma forma múltiples veces. Pero todo lo que va dentro de un guión se puede escribir directamente en la línea de ordenes.
Un guión es un fichero de texto.
Ejecución de un guión
Para hacer ejecutable un guión es necesario conceder autorización de ejecución sobre el archivo.(No hay que compilar).
Haciendo ejecutable un fichero puedo usarlo como una orden de la línea de ordenes. Este modo de ejecución provoca que el SHELL cree un subshell destinado a leer y ejecutar el contenido del guión.
Para hacer una ejecución se crea un SUBSHELL igual que el padre. Este SUBSHELL coge las líneas de una en una al fichero ejecutable.
Todo lo que hay en un guión está en la línea de ordenes. Esto mismo se puede conseguir ejecutando un proceso SHELL que precede como parámetro el nombre de un guión.
Ej
PR 1
¿ ß Ha de tener permiso de ejecución.Ksh PR1
¿ ß No necesita permiso de ejecución.
A veces resulta útil ejecutar un conjunto de ordenes en un SUBSHELL sin necesidad de crear un guión.
Para ello debo poner la lista de ordenes separadas por [ ;] y entre paréntesis. Cualquier redireccionamiento para las listas entre paréntesis afecta a todas las ordenes de la lista.
Cuando ejecutamos guiones en un SUBSHELL, todas las variaciones del entorno que generen, afectan al SUBSHELL.
Cuando deseemos que un guión del SHELL cambie el entorno del SHELL en el que dicho guión se ejecuta y no del SUBSHELL, podemos ejecutarlo de las dos siguientes formas :
Si ejecutamos el .profile : . .profile.
Comentarios en los guiones del SHELL.
Para incluir un comentario en un guión del SHELL debo incluir el carácter # (almohadilla). El SHELL considera comentario todo lo que aparezca detrás de la almohadilla hasta el salto de línea. No puedo insertar comentarios dentro de una línea, sino que tengo que ponerlo al final de la línea.
Parámetros posicionales .
Los guiones del SHELL son capaces de recibir parámetros en la llamada, para que el guión haga algo diferente.
Para usar parámetros, el SHELL utiliza unas pseudovariables llamadas parámetros posicionales cuyo valor se fija automáticamente al ejecutarse el guión.
Los más importantes son :
$# : Indica el numero de argumentos.
$1,$2,$n.. : Especifica 1º, 2º, enésimo argumento.
$0 : Especifica el nombre del programa.
$* : Da la lista completa de argumentos sin el $0.
Para reordenar los parámetros posicionales utilizo la orden SHIFT(shift). Desplazar hacia la izquierda los parámetros eliminando el primero y disminuyendo el número en uno.
Para asignar un valor a los parámetros posicionales de un guión utilizo la orden SET(set) seguida de una ejecución. Esto hace que la salida de la ejecución se asigne sobre los parámetros posicionales del guión.
En la secuencia de cadenas de ejecución de un guión interviene $? Que contiene el valor devuelto por la última sentencia de guión ejecutable.
Otras variables del Guión.
Un guión posee por defecto todas las variables externas del SHELL que lo ejecutó. Además podemos definir cualquier otra variable de la misma forma que el SHELL.
Esa variable desaparece cuando desaparece el guión.
Dentro de un guión podemos aplicar dos operadores adicionales para asignar valor a la variable en case de que esta no lo tenga.
Si lo que hacemos es una consulta la variable no declarada toma este valor por defecto.
Existen dos formas :
Si la variable no tiene valor, devuelve el valor por defecto pero no se lo asigna}
Igual que :- pero si que se lo asigna.
Ej.
$0 = pr1
P=3
echo ${P :=7} devuelve 7
echo ${D :=5} devuelve 5
echo $D devuelve 5
echo ${E :-3} devuelve 3
echo $E devuelve no definido
SENTENCIAS DE CONTROL EN LA PROGRAMACIÓN SHELL
Dentro de la programación del SHELL voy a utilizar ordenes de la línea de comandos.
Operaciones lógicas :
Evaluación de expresiones lógicas : Se realizan mediante la orden test (TEST). Test permite realizar comprobaciones sobre enteros, cadenas de caracteres y estado de ficheros. Si la comparación es cierta, test genera un código de retorno 0 y si es falsa, distinto de 0.
Los test admitidos son :
n1 -eq n2 à =
n1 -en n2 à ¹
n1 -gt n2 à >
n1 -ge n2 à >=
n1 -lt n2 à <
n1 -le n2 à <=
-z cad
à Si la longitud de la cadena es = 0.-n cad
à Si existe la cadena.cad1 = cad2
à cad1 igual a cad2cad1 != cad2
à cad1 distinto de cad2.Cadena
à Si la cadena es distinto de la cadena vacía.
-a fichero à Si existe el fichero.
-r fichero
-w fichero à Permisos del fichero.
-x fichero
-f fichero à Fichero ordinario.
-d fichero à Directorio.
-h fichero à Vínculo.
-c fichero à Especial de carácter.
-b fichero à Especial de bloque.
-p fichero à Tubería.
-s fichero à Tamaño > 0.
La orden test permite también concatenar expresiones lógicas mediante los operadores :
-a : AND
-o : OR
! : NOT
Ej.
test $# -gt 5 -a -w salida
"Si el número de parámetros del guión es mayor que cincoy se puede escribir en el fichero salida"
Una sintaxis alternativa para test consiste en situar la expresión lógica entre corchetes.
El SHELL de Korn, proporciona la orden [[ ]] que amplia el funcionamiento de test. Una expresión lógica entre doble corchete permite utilizar operadores clásicos y trata correctamente las variables nulas, es decir si una variable no es nula lo compara con la variable vacía.
ÓRDENES DE CONTROL
IF ...THEN
Sintaxis :
if orden if orden
then órdenes then órdenes
fi else órdenes
fi
El if ejecuta la orden de antes del then y si el resultado devualto es 0, ejecuta el then. Si el resultados es distinto de 0 o bien ejecuta el else, o nada.
CASE
Sintaxis :
case cadena
in
(patron/lista) orden
orden
; ;
(patron/lista) orden
orden
; ;
esac
Compara la cadena con cada caso, y si alguno coincide, ejecuta las ordenes asociadas. Cuando ejecuta las ordenes, sale del case.
(patron/lista) es un valor, o una lista de valores.
Cualquier cadena con un asterisco(*) sería el else. Si se pone el *, se debe poner siempre al final.
SELECT
La sentencia select permite comparar una cadena con un conjunto de casos, pero obliga a que la cadena se corresponda con algún caso.
Por tanto lee un valor de la entrada estándar y si no hay concordancia continua solicitando hasta que lo haya.
FOR
Sintaxis :
for variable
in lista
do
órdenes
done
Realiza una iteración para cada elemento de la lista, asignándoselo como valor a la variable.
Si no hay una lista, itera sobre los parámetros posicionales.
WHILE
Sintaxis :
while orden
do
órdenes
done
UNTIL
Sintaxis :
until orden
do
órdenes
done
Las ordenes de interrupción de bucle : Si se desea interrumpir un bucle independientemente de la condición el SHELL ofrece dos órdenes :
Las dos permiten un parámetro
Órdenes true y false :
Son 2 órdenes constantes que devuelven un valor 0 y distinto de 0 respectivamente.
OPERACIONES ARITMÉTICAS
El SHELL estándar permite realizar operaciones aritméticas mediante la orden expr.
La orden expr recibe tres parámetros (dos operadores y un operador) y muestra en la salida estándar el resultado.
Para realizar operaciones más complejas se hace uso del operador grave también llamado restitución de ordenes y que se representa con dos comillas invertidas. El operador grave ejecuta el comando entre comillas y sitúa la salida del mismo en lugar del comando. Permite que la salida de una orden forme parte de la línea de órdenes.
Ej.
expr `expr 1+2`+1
El Kshell facilita las operaciones aritméticas mediante la orden let (LET). Let permite operar con variables directamente, sin poner $, utilizan más de un operador por línea, realizan operaciones más complejas y realizan comparaciones entre enteros. Una alternativa del let es (( ))
Ej.
let x = 2*y%z
@ x = `expr ‘ expr 2*y `opr $z`
Otras órdenes del SHELL :
Órdenes de E/S :
read à Lee una línea de la entrada estándar y se la asigna a una o más variables de tal forma que la primera palabra se asigna a la primera variable, la segunda a la segunda,. Y el resto de línea a la ultima variable.
El SHELL de korn permite combinar una petición de entrada con la lectura de variable.
Ej.
read A B ? "Entrada :"
print à Sustituye en el SHELL de korn el echo y permite ampliar los formatos de este.
Otras órdenes :
trap
à La orden trap permite especificar una secuencia de acciones a realizar cuando se recibe una señal :
Sintaxis : trap "<conjunto de ordenes>" <números de señal>
Ej. trap "rm tmp$$" 2 3 15
Cuando llegue la señal 2, 3, 15 se ejecutarán las órdenes.
La señal 9 no se puede capturar.
Exit
à Provoca la finalización de un proceso puede recibir un parámetro entero que se corresponde con el código de retorno que generará el proceso al terminar. Si no hay parámetro, se devuelve un cero. Los códigos de retorno que se devuelven por convenio son :0
à terminación correcta.1
à terminación anormal.2
à error en los parámetros.
Xargs
à Muchas ordenes de UNIX no pueden recibir sus parámetros desde la entrada estándar lo que impide que otra orden pueda pasárselos mediante una tubería. La orden xargs permite redireccionar la salida de una orden como parámetros de otra.Su sintaxis es :
xargs [indicadores] [orden[(argumentos iniciales)]]
Admite dos indicadores :
-i
à toma cada línea de la entrada estándar y realiza una ejecución de la orden para esa entrada.-p
à pide confirmación.
MATRICES Y FORMA DE ACCESO
El ksh permite agrupar variables para formar un vector.
Solo admite matrices bidimensionales.
Los valores que forman una matriz tienen en común la referencia a un único nombre base de matriz entre los valores de la misma.
Los elementos de una matriz no tiene por que ser del mismo tipo.
En UNIX el concepto de variable no tiene declarado un tipo.
Las matrices no son más que un elemento lógico del programador.
Para asignar valores a un elemento de una matriz se utiliza la siguiente sintaxis :
PR[PAT] = 30
PR[ZAN] = 15
PR[LECH] = ‘no se’
Para acceder al valor de una matriz se hace mediante la siguiente sintaxis :
echo ${PR[PAT]}
Las matrices solo tiene interés cuando relaciones elementos.
Ej :
for I
in ‘cat hortalizas’
do
echo ${PR[$I]}
done