Sie sind auf Seite 1von 8

Ejercicios de programacin en shell bash o Diseo y Administracin de Sistemas y Redes n o Quinto curso de Ingenier Informtica, Universidad Rey Juan

Carlos a a

Ejercicio 1
Tenemos un laboratorio de PCs donde cada ordenador tiene un chero /etc/hosts que indica los nombres y direcciones IP de las dems mquinas. a a El chero ser similar a este: a

212.128.4.203 212.128.4.204 212.128.4.209 212.128.4.210 212.128.4.211 212.128.4.212 212.128.4.213

a202e33.escet.urjc.es a202e34.escet.urjc.es a202e39.escet.urjc.es a202e40.escet.urjc.es gamma01.escet.urjc.es gamma02.escet.urjc.es gamma03.escet.urjc.es

a202e33 a202e34 a202e39 a202e40 gamma01 gamma02 gamma03

Vamos a cambiar de direccin las mquinas gammaNN (donde NN es el nmero del ordenador). La o a u nueva direccin de cada mquina ser o a a 192.168.0.YY donde YY= NN+40 Haz un script de shell que muestre por salida estndar el nuevo fragmento de /etc/hosts. a Para el chero visto anteriormente, la salida ser a: 192.168.0.41 gamma01.escet.urjc.es gamma01 192.168.0.42 gamma02.escet.urjc.es gamma02 192.168.0.43 gamma03.escet.urjc.es gamma03 Nota: No sabemos cuntos PCs hay. No podemos suponer que el chero est ordenado. Puede haber a e huecos en la numeracin (p.e. que exitan el gamma04 y gamma06 pero falte el gamma05) o

Solucin o
#!/bin/bash fichero_entrada=/etc/hosts maquinas=$(grep gamma $fichero_entrada | cut -c44-45 ) for nn in $maquinas do yy=$(($nn+40)) echo 192.168.0.$yy done

gamma$nn.escet.urjc.es gamma$nn

Ejercicio 2
Un profesor tiene las notas de los alumnos que se presentaron a un examen en un chero de texto. Cada l nea est compuesta por el login del alumno, un espacio y su calicacin, que siempre ser apto o a o a no apto jperez apto mgarcia no apto asanche no apto mgome apto fcano apto Desea un script de shell bash que env un correo electrnico a cada estudiante, con la siguiente a o informacin: o Su nota, esto es, la l nea que le corresponda en el chero anterior El nmero de estudiantes presentados, as como el de aprobados u Ejemplo: Al estudiante mgomezse le env un correo similar a este: a mgomez apto. Presentados: 5, Aprobados: 3 (Este correo lo leer un humano, as que no son relevantes los espacios, las maysculas, etc) a u Notas: El script recibir en el argumento 1 de l a nea de comandos el nombre del chero con las notas La direccin de cada estudiante es: login@pantuo.es o En una mquina Unix, se puede enviar un correo mediante el comando mail, pasando: a El cuerpo del correo por la entrada estndar a El destinatario del correo en el argumento 1 de l nea de comandos Si el script no recibe el nombre del chero, debe mostrar un error y nalizar

Solucin o
#!/bin/bash if test $# -ne 1 then echo Uso: >&2 echo $0 fichero_de_notas>&2 exit fi suspensos=$(cat $1 | grep "no apto" | wc -l) presentados=$(cat $1 | wc -l) aprobados=$(($presentados - $suspensos)) logins=$(cat $1 | cut -d -f1 ) for login in $logins do su_nota=$(grep $login $1) estadisticas="Presentados: $presentados, Aprobados:$aprobados" echo $su_nota. $estadisticas | mail $login@pantuflo.es done

Observaciones: echo Uso: >&2 redirige la salida de echo a stderr El ltro grep apto encaja tanto en la cadena apto como en la cadena no apto El ltro grep no encaja tanto en la cadena no apto como en la cadena fcano

Ejercicio 3
Tenemos un directorio que contiene, entre otras cosas, fotos: cheros con extensin .jpg o .JPG. Las o fotos tienen mucha resolucin: Queremos reducirlas a 800x600 puntos y publicar la versin reducida en o o un web. Para reducir el tamao podemos usar el comando n convert -geometry 800x600 origen destino Para publicar en el web, basta copiar al directorio public html del home del usuario. Suponemos este directorio existente y con los permisos adecuados. Proceden de un sistema contaminado por un virus, as que hay cheros que a pesar de su extensin, o no son imgenes jpeg sino ejecutables. Si son verdaderas imgenes el comando le mostrar un mensaje a a a similar a este. imagen01.jpg: JPEG image data, EXIF standard 0.73, 10752 x 2048 Haz un script de shell bash que reciba como primer argumento el directorio, que compruebe cada chero, que lo reduzca y publica si est bin y que lo borre si est contaminado, mostrando un mensaje parecido a e a a este: imagen01.jpg imagen02.jpg imagen03.jpg CONTAMINADO. Se borra el fichero. ok. Reducida y publicado. ok. Reducida y publicado.

1 ficheros contaminados y borrados 2 ficheros reducidos y publicados.

Solucin o
#!/bin/bash if test $# -ne 1 then echo Uso: >&2 echo $0 directorio>&2 exit fi publicados=0 contaminados=0

cd $1 for i in ls *.[jJ][pP][gG] do if file $i | grep -i jpeg then convert -geometry 800x600 $i $HOME/public_html/$i publicados=$(($publicados+1)) echo $i ok. reducido y publicado else rm $i echo $i CONTAMINADO. Se borra el fichero contaminados=$(($contaminados+1)) fi done echo $contaminados ficheros contaminados y borrados echo $publicados ficheros reducidos y publicados

Ejercicio 4
En cierta asignatura, los estudiantes deben realizar una pgina web. Todos los matriculados tienen cuenta a en la mquina, aunque algunos nunca han llegado a abrir una sesin. A estos los llamaremos usuarios a o inactivos. Se desea hacer un script bash que haga una copia del web de todos los usuarios activos, que borre la cuenta de los usuarios inactivos y que muestre un pequeo informe de lo que est haciendo. n a Los requisitos se detallan a continuacin: o 1. Los usuarios matriculados tienen su home en el directorio al-03-04. Este es un fragmento del chero /etc/passwd
jperez:x:10912:1009:Juan Perez,,,:/home/al-03-04/jperez:/bin/bash mfernan:x:10913:1009:Manuel Fernandez,,,:/home/al-02-03/mfernan:/bin/bash mgarcia:x:10914:1009:Maria Garcia ,,,:/home/al-03-04/mgarcia:/bin/bash lruiz:x:10915:1009:Luis Ruiz ,,,:/home/al-03-04/lruiz:/bin/bash

2. Si un usuario es inactivo, el comando finger indicar Never logged in. a Ejemplo:


finger jperez Login: jperez Directory: /home/al-03-04/jperez Never logged in. No mail. No Plan. Name: Juan Perez Shell: /bin/bash

3. Las copias de las pginas web queremos guardarlas en a


/var/tmp/mgarcia /var/tmp/lruiz

Estos directorios no existen previamente. 4. Para hacer una copia de un web, usamos el comando wget del siguiente modo wget -m http://localhost/~mgarcia Esto copia el web de mgarcia en el directorio actual 5. El informe que muestra el programa debe ser parecido a este:
jperez. Usuario inactivo, se borra su cuenta. mgarcia. Usuario activo, copiando su web en /var/tmp/mgarcia lruiz. Usuario activo, copiando su web en /var/tmp/lruiz

Solucin o
#!/bin/bash alumnos=cat etc_passwd |grep al-03-04 | cut -d: -f1 for alumno in $alumnos do if finger $alumno | grep Never then echo $alumno. Usuario inactivo, se borra su cuenta userdel $alumno else echo $alumno. Usuario activo, copiando su web en /var/tmp/$alumno mkdir /var/tmp/$alumno cd /var/tmp/$alumno wget http://localhost/~$alumno fi done

Errores Frecuentes finger $alumno | grep Never logged in correcto: finger $alumno | grep "Never logged in" cat /etc/passwd | grep -v $alumno >/etc/passwd # INCORRECTO! Cuando el shell interpreta la redireccin de salida de grep, trunca a 0 el chero /etc/passwd. o cat /etc/passwd lee ese mismo chero, provocando una condicin de carrera. (tal vez lea a tiempo, o tal vez no) incorrecto: wget http://localhost/~$alumno > /var/tmp/$alumno Esto hace que los mensajes que wget saca por salida estndar vayan a un chero de nombre a /var/tmp/$alumno #INCORRECTO!

(esto busca la cadena Never en el chero logged y en el chero in

Ejercicio 5
Tenemos en un sistema tipo UNIX a una serie de usuarios ya creados. Hemos visto que algunos de ellos tienen su cuenta invadida por personas sin derecho a usar el equipo. Una cuenta est invadida si en el a home del usuario hay un directorio llamado .rootkit Este es un ejemplo del chero de conguracin de usuarios (passwd) o
jperez:x:10912:1009:Juan Perez,,,:/home/jperez:/bin/bash mfernan:x:10913:1009:Manuel Fernandez,,,:/home/mfernan:/bin/bash mgarcia:x:10914:1009:Maria Garcia ,,,:/home/mgarcia:/bin/bash lruiz:x:10915:1009:Luis Ruiz ,,,:/home/lruiz:/bin/bash

Queremos un script que reciba como primer parmetro el chero de conguracin de usuarios y que para a o cada cuenta: 1. Si est invadida, imprima un mensaje de alerta, la cancele (usando el comando correspondiente) y a mueva el home del usuario al directorio /invadidos/ Puedes usar el comando test -e fichero que devuelve cierto si existe el chero. 2. Si no est invadida, nos diga desde qu mquina se conect el usuario la ultima vez. Para esto a e a o puede usarse el comando finger, que para usuario que han usado alguna vez la cuenta muestra algo como esto:

bash$ finger mgarcia Login: mgarcia Name: Directory: /home/mgarcia Shell: /bin/bash Last login Sun Jun 13 15:59 (CEST) on pts/14 from sumaquina.com No mail. No Plan.

(Observa que nger coloca un espacio entre la mayor de las palabras de su salida) a

Solucin o
#!/bin/bash for usuario in $(cat $1 | cut -d: -f1) do if test -e /home/$usuario/.rootkit then echo $usuario invadido! mv /home/$usuario /invadidos userdel $usuario else desde=$(finger $usuario| grep from |cut -d -f11) echo -n $usuario entr por ultima vez desde $desde o fi done

Ejercicio 6
Tenemos un directorio que contiene, entre otras cosas, scripts de shell. Se desea modicarlos, insertando entre su primera l nea y segunda el copyright del autor y la fecha. Por ejemplo, el programa
#!/bin/bash echo hola mundo

Se quedar as a :
#!/bin/bash # (c) Juan Garcia. You can redistribute this program under the terms of the GNU General Public License. # mar abr 12 16:05:20 CEST 2005 echo hola mundo

Escribir un script de shell bash que haga esta tarea. Se usar por ejemplo de la siguiente forma: a
pon_licencia $HOME/fuentes $HOME/licencia.txt

El primer parmetro indica el directorio donde estn los fuentes. Todos llevan extensin .sh (en a a o minsculas). u La primera l nea de cada script debe respetarse, podr no ser exactamente #!/bin/bash. (Sugea rencia: siendo n el no de l neas del chero, concatena la primera l nea con el texto nuevo con las n-1 ultimas). El mensaje de copyright es una unica linea de texto, que est en el chero que se pasa como segundo a parmetro. La fecha es la que proporciona el comando date. Ni el chero con la licencia incluye la a almohadilla # ni la salida del comando lo muestra. El script debe comprobar que recibe exactamente 2 parmetros, que el primero es un directorio y a el segundo un chero legible. Si alguno de estos requisitos no se cumple, se muestra por stderr un mensaje de error especicando el problema. (Recuerda que para mostrar un mensaje por stderr basta con redirigir texto a &2)

Solucin o
#!/bin/bash if [ $# -ne 2 ] then echo "uso: $0 directorio licencia " exit fi if ! [ -d $1 ] then echo "$1 no es un directorio" exit fi if ! [ -r $2 ] then echo "$2 no se puede leer" exit fi

>&2

>&2

>&2

directorio=$1 licencia=$2 cd $directorio for script in *.sh do n=$(cat $script | wc -l) ene_menos_uno=$(($n - 1)) head -1 $script > aux echo -n \# >> aux cat $licencia >> aux echo -n \# >> aux echo $(date) >> aux tail -$ene_menos_uno $script >>aux mv aux $script done

Errores Frecuentes
fecha=date #MAL! Esto asigna a la variable fecha la cadena date. Si queremos que se ejecute el comando date, hay que usar $() o las comillas invertidas cat $1 | grep *.sh # MUY MAL!

El comando para ver el contenido de un directorio es ls. Si queremos ver todos los cheros de extensin .sh, basta hacer ls *.sh o El comando cat recibe como argumento uno o ms cheros. Si recibe uno, muestra su contenido por a stdout. Si recibe ms de un chero, muestra por stdout el contenido de uno tras otro, concatenados. a Cuando escribimos grep *.sh, el shell expande el asterisco. Supongamos que en el directorio actual tenemos los cheros script_01.sh, script_02.sh y script_03.sh. El comando grep recibir estos a tres argumentos, exactamente igual que si hubieramos escrito grep script_01.sh script_02.sh script_03.sh Por tanto intenta buscar la cadena script 01.sh en los cheros script 02.sh y script 03.sh echo # > fichero echo \# >> fichero o bien echo # >> fichero # Lleva almohadilla y fin de linea al fichero Tambien hay que tener en cuenta que echo muestra por su salida estndar el argumento que recibe a y un n de l nea. Para omitir el n de linea debemos pasar el prametro -n a 7 #MAL # Lleva almohadilla y fin de linea al fichero

Todo lo que hay tras una almohadilla es un comentario. A menos que escapemos la almohadilla

echo -n # >> fichero

# Lleva almohadilla al fichero, sin fin de lnea

Otra forma de evitar el n de linea ser pasar varios argumentos a echo a echo \# $(cat $licencia) >> aux

Das könnte Ihnen auch gefallen