0% encontró este documento útil (0 votos)
44 vistas

Taller Shell

Este documento presenta tres scripts en shell que validan y muestran información sobre archivos y directorios recibidos como parámetros. El primer script muestra los permisos de un archivo o directorio. El segundo script valida y muestra detalles de múltiples archivos y directorios. El tercer script valida si un directorio existe y muestra todos sus subdirectorios y archivos. Además, explica conceptos como el paso de parámetros, variables especiales y la escritura de scripts en shell.
Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
44 vistas

Taller Shell

Este documento presenta tres scripts en shell que validan y muestran información sobre archivos y directorios recibidos como parámetros. El primer script muestra los permisos de un archivo o directorio. El segundo script valida y muestra detalles de múltiples archivos y directorios. El tercer script valida si un directorio existe y muestra todos sus subdirectorios y archivos. Además, explica conceptos como el paso de parámetros, variables especiales y la escritura de scripts en shell.
Derechos de autor
© © All Rights Reserved
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 7

TALLER : SCRIPT EN SHELL

1. Recibir un nombre de archivo como parámetro e indicar imprimir todas las ayudas
que corresponda si el archivo es de lectura, escritura y ejecución por el usuario.
#upunto1.sh

#indica las leyendas de un nombre de archivo dado

#
clear

if [ -f ${1} ] || [ -d ${1}];
then
#valida si existe archivo o directorio

echo `ls -lt $1`


#mostrar leyendas

else

echo "No existe ni archivo ni directorio con ese nombre o similar"

fi

echo

#Fin punto1.sh

2. Recibir varios nombres de archivo como parámetro….. validar si el nombre


corresponde y mostrar en pantalla
#punto2.sh
#valida varios nombres si es archivo o directorio y muestra en la pantalla

clear
echo cantidad de parametros ingresados $·
#muestra el numero de parametros
echo Archivos Encontrados:: $* #
#cada uno de los parame. en orden de ingreso
echo
for i in $*
do
if [ -f ${i} ] && [ -d ${i} ] ;
then
#si son ambos
echo `ls -lt ${i}`
echo "El nombre corresponde para ambos (archivo comun y directorio)"
elif [ -f ${i} ];
then
#si es un archivo comun
echo `ls -lt ${i}`
echo "El nombre corresponde a un archivo comun"
elif [ -d ${i} ]; then
#si es un directorio
echo `ls -d -lt ${i}`
echo "El nombre corresponde a un directorio"
else
echo "No existe ni archivo ni directorio con ese nombre o similar"
fi
echo
done
#Fin punto2.sh

3. Recibir un nombre de directorio si existe y mostrar nombre de todos los directorio y


subdirectorios, dar el nombre de todos los directorios
#punto3.sh
#valida si existe un directorio y mostrar
# todos sus directorios y subdirectorios
#
clear
if [ -d $1 ] ;
then
#valida si q dato es un directorio
echo
result=`ls -R $1 |
grep ":$" | sed -e 's/:$//'` #
#mostrar dir. y subdir.
echo `cat $result` #
#muestre los resultados por lineas
else
echo "No existe ningun directorio con ese nombre o similar
fi
echo
#Fin punto3.sh

PASO DE PARÁMETROS A UN PROGRAMA DE SHELL


A menudo queremos que nuestros programas de shell reciban parámetros desde la línea de órdenes para hacerlos más
versátiles. Estos parámetros son lo que se conoce como parámetros de posición. Los parámetros de posición se pueden
usar dentro de un programa de shell como cualquier otra variable de shell; es decir, para saber su valor utilizaremos el
símbolo $. Los parámetros dentro del shell script son accesibles utilizando las variables:
$0 Representa al parámetro cero o nombre del programa
$1 Representa al parámetro uno
$2 Representa al parámetro dos

$9 Representa al parámetro nueve
${10} Representa al parámetro diez
${11} Representa al parámetro once

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

ALGUNAS VARIABLES ESPECIALES DEL SHELL


$# Número de parámetros que han pasado a la shell.
1 PROGRAMACIÓN DE SHELL SCRIPTS EN LINUX
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
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 2
echo Ahora el parámetro \$1 vale: $1
echo Ahora el parámetro \$2 vale: $2
echo Ahora el parámetro \$3 vale: $3
echo Ahora el parámetro \$4 vale: $4
echo El número total de parámetros es: $#
echo Todos los parámetros recibidos son: $*
Mostrará el siguiente resultado:
$./ej_shift2 uno dos tres cuatro cinco seis
El nombre del programa es: ./ej_shift2
Todos los parámetros recibidos son: uno dos tres cuatro cinco seis
El primer parámetro recibido es: uno
El segundo parámetro recibido es: dos
El tercer parámetro recibido es: tres
El cuarto parámetro recibido es: cuatro
Ahora el parámetro \$1 vale: tres
Ahora el parámetro \$2 vale: cuatro
Ahora el parámetro \$3 vale: cinco
Ahora el parámetro \$4 vale: seis
El número total de parámetros es: 4
Todos los parámetros recibidos son: tres cuatro cinco seis
La orden shift desplaza todas las cadenas en * a la izquierda n posiciones y decrementa # en n. Si a shift no se le indica el
valor de n, por defecto
El número total de parámetros es: 6

Escritura de scripts de shell


Hemos llegado a un punto donde podemos realizar tareas más complejas a partir de los comandos aprendidos y es aquí donde radica el
poder del intérprete de comandos bash. Como veremos a continuación, el intérprete de comandos es un poderoso lenguaje para realizar
script que permitan unir varios comandos para realizar una tarea un poco más compleja (y es el este el poder principal de todo Un*x). El
único requisito es tener nociones básicas de programación para poder sacar todo el provecho posible de esta característica del intérprete
de comandos. En todo caso, con un poco de práctica y un buen sentido de la lógica se podrán hacer también script poderosos para
desarrollar las tareas que requerimos.

Deberemos saber también que con la ayuda solamente de la conjunción de comandos no podremos hacer script verdaderamente
interesantes. Por esto se incorporan las construcciones de shell. Estas son las construcciones while, for-in, if-then-fi y case-
esac. Existen muchas más pero estas serán las más útiles para nosotros en estos momentos. Para mayor información sobre otro tipo de
construcciones seria mejor revisar las páginas de manual del intérprete de comandos bash (man bash).

Empezaremos viendo un uso sencillo de la construcción for-in que tiene la siguiente sintaxis

for var in word1 word2


do
commandos
done
Para poder usar esto, podríamos realizar una lista de directorios que querramos nosotros de una sola vez

for dir in /bin /etc /lib


do
ls -R $dir
done
Esto hará un listado recursivo 3 veces. La primera vez que pase por el ciclo, la variable $dir tomará el valor /bin, la segunda será
/etc y la tercera /lib.

Podríamos prescindir del par do-done con el uso de llaves ({})

for dir in /bin /etc /lib


{
ls -R $dir
}
Ya hemos visto anteriormente la idea de argumentos en la utilización de comandos y programas; pero deberemos ver como se realiza la
codificación de un script para tomar estos argumentos. Como antes dijimos, los argumentos eran pasados a los programas para que estos
lo utilizaran. En la construcción de script veremos lo que se llaman variables posicionales cuyo valor corresponde a la posición del
argumento luego del nombre del script. Supongamos que tenemos un script que toma 3 argumentos. El primero será el nombre de un
directorio, el segundo el nombre de un archivo y el tercero es una palabra a buscar. Este script buscará en todos los archivos del
directorio, cuyo nombre incluya el nombre de archivo que le pasamos como argumento, la palabra que también le estamos pasando. El
script se llamara miscript y estará compuesto del siguiente código

ls $1 | grep $2 | while read ARCHIVO


do
grep $3 ${1}/${ARCHIVO}
done
La sintaxis será

miscript [directorio] [nombre_archivo] [palabra]

Aquí tenemos varias cosas para ver. Primero que nada, el uso de las variables posicionales. Como se podrá apreciar el número de la
variable, que esta precedido por un signo $, indica la posición del argumento cuando el script es llamado. Solamente se podrán usar 9
variables de este tipo sin tener que emplear un pequeño truco de corrimiento que veremos luego, dado que el 0 representa al nombre del
script mismo. Es decir que en este caso la variable posicional $0 valdrá "miscript". Como se puede ver se han utilizado canalizaciones
para poner más de un comando junto. Al final de la construcción se esta usando una construcción while. Esta se usa para repetir un
ciclo mientras una expresión sea cierta.

while ($VARIABLE=valor)
do
commandos
done
En este caso esta siendo usada al final de una canalización con la instrucción read ARCHIVO. Es decir, mientras pueda leer el
contenido de la variable $ARCHIVO, continuar. Esta variable $ARCHIVO contiene el resultado de lo que arrojo la canalización del listado
con la salvedad de que tenia que contener la palabra que le enviamos como argumento, es así que solo se imprimirán las líneas en las
que coincida la palabra a buscar de los archivos que cumplan con los requisitos.

Otra cosa a tener en cuenta es una nueva construcción en este script, ${1}/${ARCHIVO}. Al encerrar un nombre de variable dentro de
llaves podemos combinarlas. En este caso forman el nombre del directorio ( ${1}) y añadimos una / como separador del directorio, y
seguido e nombre del archivo donde se aplicara el comando grep con la palabra a buscar $3.

Podríamos hacer que este script sea un poco más documentado. Para esto podríamos asignar las variables posicionales a otras variables
para que se pueda entender mejor su uso.

DIRECTORIO=$1
ARCHIVO_BUS=$2
PALABRA=$3

ls $DIRECTORIO | grep $ARCHIVO_BUS | while read ARCHIVO


do
grep $PALABRA ${DIRECTRIO}/${ARCHIVO}
done
El número de las variables posicionales que pueden usarse en un script, como antes dijimos, se encuentra restringido a 10. ¿Qué pasaría
si tenemos más de 9 argumentos? Es aquí donde tenemos que usar la instrucción shift. Esta instrucción mueve los argumentos hacia
abajo en la lista de parámetros posicionales. De esta manera podríamos tener una construcción con esta distribución de variables

DIRECTORIO=$1
shift
ARCHIVO_BUS=$1
De esta manera podríamos asignar el valor de la primer variable posicional a la variable DIRECTORIO y luego el siguiente argumento
que habíamos dado se tomara otra vez con el nombre de $1. Esto solo tiene sentido si asignamos las variables posicionales a otra
variable. Si tuviéramos 10 argumentos, el décimo no estaría disponible. Sin embargo, una vez que hacemos el que las variables se corran
de posición este se convertirá en el noveno y se accederá por la variable posicional $9. Existe una forma también de pasar como
argumento a la instrucción shift el número de posiciones que queremos correr. Por lo cual podemos usar

shift 9
y así se lograra que el décimo argumento sea el parámetro posicional 1.

Lo que ocurre con los anteriores 9 argumentos es que desaparecen si no se los asigno a una variable anteriormente. Podremos cambiar
usar un nuevo parámetro que podrá contener mas de un parámetro pasado al script. Este se denomina $* y contendrá el resto de los
argumentos que se pasen al script luego de que se haya realizado un corrimiento determinado. Por ejemplo, si quisiera buscar una frase
en lugar de una única palabra el script podría ser

DIRECTORIO=$1
ARCHIVO_BUS=$2
shift 2
PALABRAS=$*

ls $DIRECTORIO | grep $ARCHIVO_BUS | while read ARCHIVO


do
grep "$PALABRAS" ${DIRECTRIO}/${ARCHIVO}
done
Lo que aquí cambio es que luego de haber asignado a variables los parámetros posicionales 1 y 2 las variables fueron desplazadas dos
veces, eliminando los dos primeros argumentos. Luego asignamos los argumentos restantes a la variable PALABRAS. Para que sea
tomado como una cadena, se lo encerró entre comillas para ser pasado al comando grep, si no lo hiciéramos el bash vería nuestra
entrada como argumentos individuales para pasar al grep.

Otro parámetro que es de utilidad es el $# que lleva la cuenta de la cantidad de argumentos pasados al script. De esta forma podríamos
realizar un script que identificara si se le están pasando la cantidad de parámetros que realmente necesita y anunciar el error si faltaran
estos. Para ello utilizaremos la construcción if-then-fi que es muy parecida a la while-do-done, en donde el par if-fi marca
el final de un bloque. La diferencia entre estas construcciones es que el if solo evaluara una vez la condición. La sintaxis es la siguiente

if [ condición ]
then
hacer_algo
fi
Las condiciones que puede usarse se encuentran en las man page test (man test). Nosotros usaremos una simple condición para contar
argumentos, pero pueden ser usadas distintas condiciones como nombres de archivos, permisos, si son o no directorios, etc. Para saber si
la cantidad de argumentos que se nos a pasado en el script es correcta, utilizaremos una opción aritmética que compare la cantidad de
argumentos pasados ($#) con un número que nosotros estipularemos, en este caso 3. Pueden usarse diferentes opciones con el formato
arg1 OP arg2, donde OP será alguno de los siguientes

-eq es igual
-ne no es igual
-lt menor que
-le menor que o igual
-gt mayor que
-ge mayor que o igual
Se usará en este caso el -ge (mayor o igual que) dado que si la cantidad de argumentos que siguen al segundo es mayor la tomaremos
como una frase a buscar y si es igual como una palabra. Lo único que haremos en caso de que la cantidad de argumentos sea menor,
será informar de esto y de la forma de usar el script.

DIRECTORIO=$1
ARCHIVO_BUS=$2
shift 2
PALABRAS=$*

if [ $# -ge 3 ]
then
ls $DIRECTORIO | grep $ARCHIVO_BUS | while read ARCHIVO
do
grep "$PALABRAS" ${DIRECTRIO}/${ARCHIVO}
done
else
echo "Número de argumentos insuficientes"
echo "Use: $0 <directorio> <archivo_a_buscar> <palabras>"
fi
Otra utilidad para del if, es la posibilidad de realizar lo que se denomina if anidados. De esta forma podríamos tener varias capas de if-
then-else-fi. Como ejemplo podría ser esta una construcción válida

if [ $condicion1 = "true" ]
then
if [ $condicion2 = "true" ]
then
if [ $condicion3 = "true" ]
then
echo "las condiciones 1, 2 y 3 son ciertas"
else
echo "solo son ciertas las condiciones 1 y 2"
fi
else
echo "condición 1 es cierta, pero no la 2"
fi
else
echo "la condición 1 no es cierta"
fi
Podríamos también hacer que una sola variable tome diferente valores e interactuar con ella para ver si se cumple la condición buscada.
De esta forma podríamos por ejemplo hacer un menú de usuario con distintas alternativas. Pero esta forma es útil solo para pocas
condiciones. ¿Que pasaría si tuviéramos muchas condiciones mas que agregar? Se nos haría por demás de complicado seguir el
esquema armado y sería demasiado código para lo que se trata de realizar. Es aquí es donde se necesita la estructura case-esac.
Como se podrá ver, al igual que en el if-fi aquí el inverso de case (esac) cierra la construcción. Veamos un ejemplo de una
construcción con case

read ELECCION
case $ELECCION in
a) programa1;;
b) programa2;;
c) programa3;;
*) echo "No eligió ninguna opción valida";;
esac
Hay que tener en cuenta algunas cosas respecto a este tipo de construcción. Por ejemplo el mandato que le damos al principio read indica
al bash que tiene que leer lo que se ingrese a continuación y lo guarde en una variable que se llamara ELECCION. Esto también será útil
para el uso de otras construcciones ya que el read no es propiedad exclusiva de la construcción esac, sino que pertenece al mismo
bash. Como se ve, se le indica que si el valor que la variable contiene es igual a alguna de las mostradas debajo se ejecute determinado
programa. (case $ELECCION in). La elección se debe terminar con un paréntesis ")" para que se cierre las posibilidades. Podríamos
poner más posibilidades para cada elección; lo único que hay que recordar es cerrar con un paréntesis. El punto y coma nos marca el final
de un bloque, por lo que podríamos agregar otro comando y se cerrara con punto y coma doble al último. El asterisco del final nos indica
que se hará en caso de que no coincida lo ingresado con ninguna de las posibilidades. Un ejemplo, sería que nuestra construcción
reconozca mayúsculas y minúsculas y además ejecute más de un comando por bloque.

read ELECCION
case $ELECCION in
a|A)
programa1
programa2
programa3;;
b|B)
programa4
programa5;;
c|C)
programa3;;
*)
echo "No eligió ninguna opción valida";;
esac
También se podría haber incluído un rango de posibilidades

echo "Ingrese un caracter: "


read ELECCION
case $ELECCION in
[1-9]) echo "Usted ingreso un número";;
[a-z]) echo "Usted ingreso una letra minúscula";;
[A-Z]) echo "Usted ingreso una letra mayúscula";;
esac
Hay que recordar que todos estos script podrán estar en un archivo, pero para que se ejecuten se le deberá primero dar los permisos
pertinentes. Un par de cosas a tener en cuenta para la construcción de script son la forma en que se quiere que ejecute éste y la captura
de teclas. Al ejecutarse un script de shell, se estará creando un bash hijo que lo ejecutará. Dado que las variables y funciones pertenecen
al intérprete de comandos que las creó, al finalizar el script el proceso hijo del bash morirá y con el todos los seteos de variables y
funciones. Por esto, si se quisiera que los cambios de las variables y las funciones que se definieron permanezcan para ser utilizables una
vez que el script haya terminado, se deberá comenzar a ejecutar el script con un punto "." seguido por un espacio antes del nombre de
éste. De esta forma el proceso del intérprete de comando actual sera quien ejecute el script con lo que se conservaran todas las variables
y funciones.

[shrek@pantano:~]$ . miscript
Un script puede dejar cosas sueltas antes de terminar si éste es finalizado bruscamente enviándole una señal de finalización [1] ya sea
con la combinación de teclas Ctrl-C o con un kill -15. Para esto se deberán capturar estas señales para poder hacer una limpieza, ya
se de variables o archivos, antes de finalizar. La forma de hacerlo es con el uso del comando trap; de esta forma se capturará la señal que
se le envíe al script y se podrá ya sea ignorar la misma o ejecutar otro comando de limpieza. Para demostrar esto haremos un pequeño
script que servirá de menú. La llamada al script del menú podría estar en el archivo .profile del usuario o en el .bash_profile. Si
lo que no queremos es que el usuario salga del script con usando la combinación de teclas Ctrl-C, lo que haremos es capturar la señal y
hacer que se ejecute nuevamente el script que se llamará simplemente menu.

trap './menu' 2
while :
do
echo 'a) Listado de archivos'
echo 'b) Día y hora actual'
echo 'c) Mes actual'
echo 'Seleccione: '
read ELECCION
case $ELECCION in
a|A) ls;;
b|B) date;;
c|C) cal;;
*) echo "No eligió ninguna opción valida";;
esac
done
Como se ve al principio del script se utiliza el comando trap que al captura la señal 2 (SIGINT) que produce el Ctrl-C relanza el script. Al
final del script se ve que se llama nuevamente dado que al ejecutarse el comando de cada elección se quiere que el menú siga
funcionando. Practicar con estas construcciones será de gran ayuda para entender el proceso de construcción de script y los preparara
para script más complejos usando otros interpretes como el sed, awk y el lenguaje perl. Para mayor información respecto a la
construcción de script, remitirse a las páginas de manual del intérprete de comandos, en este caso man bash.

También podría gustarte