gnuservers.com.ar - Respuestas a los ejercicios

Estas son las respuestas a los ejercicios planteados aquí. En muchas situaciones no hay una sola respuesta para el ejercicio planteado, se indican aquí algunas respuestas posibles.

Preguntas teóricas generales

  1. ¿Por qué decimos que "Linux" es solamente el kernel del sistema operativo que utilizamos?

    Linux es el nombre del kernel del sistema operativo GNU/Linux. El resto del sistema fue desarrollado por el proyecto GNU y por eso se llama GNU/Linux.

  2. ¿Qué representa cada una de las columnas que vemos por pantalla al ejecutar un ls -l?
    -rw-r--r--    1 marga    marga           0 2003-02-08 00:42 test
    La primera columna indica si se trata de un directorio (d), un archivo (-), un symlink (l), etc. A continuación se indican los permisos del archivo, para el dueño, el grupo y el resto de los usuarios. La segunda columna indica la cantidad de links al inodo, la tercera y la cuarta son el dueño y el grupo del archivo. La sexta columna inidica el tamaño del archivo, seguida por la fecha y la hora de modificación, y finalmente el nombre del archivo.

  3. Explique porqué no se puede crear un "hard-link" en el disco rígido, de un archivo que se encuentra en un diskette.

    Cada sistema de archivos tiene su propia tabla de inodos, crear un hard-link es asignarle un nombre a un inodo. Si creamos un hard-link a un archivo que se encuentra en otro sistema de archivos (en este caso el diskette), tendríamos el numero de inodo de ese archivo en el otro sistema de archivos y ese número podría apuntar a un inodo del sistema de archivos donde se está creando el hard link (en este caso el disco rígido) que contenga otros datos completamente distintos al inodo que se quiere utilizar.
    En definitiva, no es posible crear hard-links entre distintos sistemas de archivos, porque esto llevaría a inconsistencias en la información.


  4. ¿Que son los meta-caracteres de shell? ¿Para qué se utilizan? Cite algunos ejemplos.

    Los meta-caracteres de shell son caracteres especiales que son interpretados por el shell antes de que la información sea enviada a los comandos.
    De esta manera, ejecutar echo * no el envía al comando echo un *, sino que le envía el listado de todos los archivos y directorios que se encuentran en el directorio actual.
    Ejecutar ps ax > procesos, por otro lado, hace que la salida del comando ps no se vea en la pantalla del usuario, sino que se guarde en el archivo procesos.
    Si se ejecuta ls -l ?????, se obtendrá un listado con toda la información de los archivos que tengan cinco letras en su nombre.
    Y si se ejecuta (sleep 300; echo "Ya está el agua para el té") &, el shell devuelve la línea de comandos inmediatamente, pero a la vez se genera un proceso que espera 5 minutos y luego muestra un mensaje por pantalla avisando que ya está hirviendo el agua.


  5. ¿Cómo se determina en los sistemas UNIX el tipo de un archivo?

    En los sistemas UNIX el tipo de un archivo no se determina por su extensión, sino por su contenido. El comando file analiza el contenido de un archivo y determina el tipo del mismo, según una serie de reglas.

  6. ¿En qué consiste el dispositivo /dev/tty

    El dispositivo /dev/tty es la consola actual que está utilizando el usuario. De modo que ejecutar el comando echo Hola > /dev/tty, mostrará "Hola" en la pantalla del usuario.

  7. ¿Qué es una variable de entorno? ¿Qué variables de entorno son heredadas por las aplicaciones que se ejecutan?

    Una variable de entorno es una de las variables que pertenecen al sesión de un determinado usuario. Muchas de estas variables adquieren un valor en el momento que el usuario ingresa al sistema, mientras que algunas otras pueden adquirir un valor posteriormente, si el usuario ejecuta variable=valor. Las únicas variables de entorno que son heredadas por las aplicaciones son aquellas que fueron exportadas usando el comando export.

  8. ¿Cuál es la función principal de un "filtro"? Cite algunos filtros y su funcionalidad básica.

    Los filtros son programas que procesan una determinada entrada y muestran una salida relacionada con la entrada recibida. cat, uno de los filtros más sencillos, simplemente muestra una salida idéntica a la entrada. head y tail, otros filtros bastante sencillos, muestran el principio y el final de la entrada respectivamente. grep, un filtro bastante más avanzado, muestra únicamente ciertas líneas de la entrada, según el patrón y las opciones que se le indiquen.

  9. ¿En que consiste una "Expresion Regular"? Dé algunos ejemplos.

    Una expresión regular es una cadena de caracteres que se utiliza para concordar con palabras o líneas de texto de una forma más o menos compleja. Una palabra sencilla, como "Nicolás" por ejemplo, puede ser una expresión regular, ya que coincidiría con todas las apariciones de la palabra Nicolás. Pero las expresiones regulares son mucho más poderosas, permiten especificar que una palabra esté al comienzo o al final de la línea, que tenga un rango de caracteres en medio, etc, etc.
    Por ejemplo, la expresión ^A.*o$, coincidirá con las líneas que comiencen con A y terminen con o, esto podría coincidir tanto con "Alejandro" como con "Antes de ayer vi un mono". La expresión ^P[^ ]*o$, por otro lado coincidirá con las palabras que comiencen con P, terminen con o y no tengan ningún espacio en medio, es decir, podrá coincidir con "Pedro" o "Pablo", pero no con "Paso a paso".


Ejercicios Prácticos - Básicos

  1. Además del comando "who" existe otro comando similar: "w". Utilice el manual del comando "w" para explicar qué significa la salida que obtenemos al ejecutarlo.

    El comando w es una combinación del comando who y el comando uptime.
    15:20:53 up 9 days, 17:08,  9 users,  load average: 0.00, 0.01, 0.00
    USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
    maxy     tty1     -                24May03  6days 10.20s  0.05s /bin/sh /usr/bi
    marga    pts/3    :0.0             14:13    0.00s  0.11s  0.05s w
    maxy     tty2     -                24May03  8days  0.89s  0.76s mc
    marga    pts/5    :0.0             13:14    2:10m  0.06s  0.06s bash
    (...)
    			
    En la salida podemos ver una primera línea que incluye la hora, el tiempo que hace que el sistema está prendido, la cantidad de usuarios y la carga promedio del sistema el los últimos 1, 5 y 15 minutos. A continuación, muestra los usuarios del sistema, incluyendo la consola en la que están conectados, la fecha de ingreso al sistema, el tiempo que hace que no realizaron ninguna acción, la cantidad de tiempo de procesador que han utilizado hasta el momento, la cantidad de tiempo del procesador que ha utilizado el proceso que están ejecutando en este momento, y el proceso que se está ejecutando en este momento.

  2. ¿Que comando debemos ejecutar para crear un symlink llamado "HOWTO", al directorio "/usr/share/doc/HOWTO/es/HOWTO"?

    Simplemente: ln -s /usr/share/doc/HOWTO/es/HOWTO HOWTO

  3. Ejecute touch #foo.c, explique lo que sucede.

    touch #foo.c
    touch: file arguments missing
    Try `touch --help' for more information.
    
    Lo que sucede es que el # es el caracter que el shell utiliza para comentarios, de manera que todo lo que está a continuación del # no se le envía al comando touch, y por lo tanto touch no recibe ningún parámetro.

Ejercicios Prácticos - Archivos, permisos y propiedad

  1. ¿De qué manera podemos evitar que los otros usuarios puedan ver el contenido de un directorio?

    Si el directorio en cuestión se llama, por ejemplo, "secretos", podríamos ejecutar chmod 711 secretos, con lo que quitaríamos el permiso de lectura, necesario para ver el contenido del directorio. También podríamos ejecutar chmod go-rwx secretos para quitarle todos los permisos tanto al grupo como a los otros usuarios.

  2. ¿Cómo podemos hacer para que el archivo "ulises" tenga los siguientes permisos?

  3. ¿Qué permisos asigna el comando "chmod 755 /bin" ? ¿Por qué, cuando ejecutamos este comando, nos dice que no poseemos los permisos necesarios?

    Ese comando le dá todos los permisos al dueño del directorio (root), y permisos de lectura y ejecución a los miembros del grupo y al resto de los usuarios.
    Cuando lo tratamos de ejecutar nos dice que no tenemos los permisos necesarios para ejecutarlo, porque solamente el dueño del archivo (o el administrador del sistema puede cambiar los permisos a un archivo o directorio, y en este caso el dueño es root, y no un usuario común.


  4. Explique qué permisos asignan o desasignan los siguientes comandos:

  5. Sobre el directorio /usr/bin
  6. Sobre el directorio /etc

Ejercicios Prácticos - Scripts de Shell

  1. Cite por lo menos dos maneras distintas de ejecutar un script de shell.

    sh script.sh, o también ./script.sh (si el archivo tiene permisos de ejecución).

  2. Crear un script de Shell que monte la diskettera, copie todos los archivos (incluyendo subdirectorios) de la diskettera a un directorio que se pase como parámetro, y luego desmonte la diskettera. (Ayuda: para copiar tambien los subdirectorios, debe utilizarse un comando recursivo)
    mount /floppy
    cp -r /floppy $1
    umount /floppy
    
  3. Crear un script de Shell que liste únicamente los nombres de los directorios que se encuentran a partir del directorio actual.
    for i in `ls`; do
    	if [ -d $i ]; then
    		echo $i
    	fi
    done
    
  4. Realizar un script que espere hasta que un determinado proceso se ejecute. Y cuando ese proceso se ejecuta, matarlo. (Ayuda: utilizar el comando killall).
    while true; do
            if ps ax | grep $1 | grep -v ' grep '; then
                    killall $1
            fi
    done
    
  5. Crear un script que reciba un directorio como primer parámetro, y a continuación una lista de archivos. El script debe validar que los parámetros recibidos sean realmente archivos y luego copiarlos al directorio recibido.
    if [ -d $1 ]; then
            nombre_dir=$1
            shift
            for i in $*; do
                    if [ -f $i ]; then
                            cp $i $nombre_dir
                    else
                            echo "El archivo $i no es válido"
                    fi
            done;
    else
            echo "El primer parámetro debe ser un directorio!"
    fi
    
    Hay muchas más variantes de este script, algunas más sencillas y otras mucho más complicadas. Esta es sólo una de todas las posibles.

Ejercicios Prácticos - Filtros

  1. ¿Qué comando debe ejecutarse para contar la cantidad total de caracteres contenidos en todos los archivos del directorio actual?

    cat * | wc -c

  2. Realizar un script de Shell que compare dos archivos (que se reciben como parámetro) y diga por pantalla cuál de ellos tiene mayor cantidad de líneas.
    cant1=`cat $1 | wc -l`
    cant2=`cat $2 | wc -l`
    if [ $cant1 -gt $cant2 ]; then
            echo "$1 tiene más líneas que $2"
    else
            if [ $cant1 -lt $cant2 ]; then
                    echo "$2 tiene más líneas que $1"
            else
                    echo "$1 y $2 tienen la misma cantidad de líneas"
            fi
    fi
    

Ejercicios Prácticos - Expresiones regulares

  1. ¿Qué debemos ejecutar para listar todos los archivos que tienen permiso de lectura, escritura y ejecución para los "otros"?
    ls -l | grep '^.......rwx'

  2. Crear un script que lea un archivo de entrada, y guarde en otro archivo de salida, las líneas que comienzan con una vocal (mayúscula o minúscula).
        grep '^[AEIOUaeiou]' entrada > salida

    Extensión: recibir los nombres de los archivos por parámetros.
        grep '^[AEIOUaeiou]' $1 > $2
  3. Realizar una expresión regular que concuerde lo mejor posible con números telefónicos, tanto de formato internacional como nacional.
    Ejemplos de números válidos: ++54-11-4652-8589 // 4512-8874 // 43-9856
    Ejemplos de números no válidos: 5--8558 // 4586- // ++--8759
    egrep '^(\+\+)?[0-9]+-?[0-9]+-?[0-9]+$' telefonos
    Se asume que el archivo telefonos tiene una serie de teléfonos, de a uno por línea.

  4. El patrón .*@[^.]*\..* ¿Con qué tipo de cadena concuerda? ¿Puede mejorarlo?

    Se trata de un patrón pensado para concordar con direcciones de email. Dado que las direcciones de email suelen ser muy complejas, hacer un patrón perfecto es casi imposible, pero una mejora sobre la expresión anterior podría ser:
    '^([a-zA-Z0-9_-]+\.)*[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+\.([a-zA-Z0-9_-]+\.)*[a-zA-Z0-9_-]+$'
  5. Realice un script que, leyendo el diccionario del sistema, almacene en un archivo la cantidad de palabras que empiezan con a, las que empiezan con b, las que empiezan con c, etc.
    for i in a b c d e f g h i j k l m n o p q r s t u v w x y z; do
            echo -n "$i: "
            grep "^$i" /usr/share/dict/words | wc -w
    done > $1