Planificación y Control de Procesos en UNIX Autor: Sergio Lozano Enero 2003 OBJETIVOS En muchos sistemas UNIX es necesario lanzar procesos a ejecución automáticamente sin presencia de un usuario, como por ejemplo las tareas propias de mantenimiento preventivo de un sistema de gestión de red. A su vez, para tener un óptimo rendimiento de un sistema como el nombrado es necesario controlar en todo momento el consumo que los procesos tienen sobre los recursos del sistema. El objetivo de este trabajo es conocer las herramientas existentes en UNIX para la planificación, la administración y el control de procesos, y comprender todas las posibilidades de los diferentes comandos, elaborando programas en shell a modo de ejemplo. También se elaborará un programa en shell que aúne todos los conceptos vistos en este trabajo. INDICE 1. Planificación de tareas en UNIX. 1.1. Introducción. 1.2. Comandos at, atq y atrm. 1.3. Comando batch. 1.4. Comandos cron y crontab. 1.5. Diseño de un shell-script: Automatización de procesos. 2. Administración de procesos en UNIX. 2.1. Introducción. 2.2. Como se inicia un proceso. 2.3. Monitorización de procesos. 2.3.1. Monitorizar procesos desde el entorno de ventanas. 2.3.2. Monitorizar el estado de los procesos: ps. 2.4. Control de procesos. 2.4.1. Cambiar la prioridad de procesos: nice, snice y renice. 2.4.2. Matar procesos: kill. 2.4.3. Ejecución de procesos en segundo plano. 2.5. Monitorización del sistema. 2.5.1. Monitorizar la cantidad de espacio en disco: du y df. 2.5.2. Monitorizar el estado de memoria: free. 2.5.3. Monitorizar la carga del sistema: top y time. 2.6. Diseño de un shell-script: Control de carga del sistema. 3. Descarga automática de archivos con control de carga en sistema. -ACSO 1- -Página 2 de 22- 1. PLANIFICACIÓN DE TAREAS EN UNIX. 1.1. Introducción. Todo sistema operativo tipo UNIX pone a disposición del usuario varias herramientas para poder lanzar procesos de forma automatizada cuando consideremos oportuno, sin necesidad de la intervención de un operador. Las tareas automatizadas suelen emplearse para realizar tareas repetitivas que se ejecutan a intervalos de tiempo regulares y que no requieren el control o presencia de un usuario. Un ejemplo de este tipo de tareas puede ser la realización de estadísticas de un sitio web o la generación de copias de seguridad del sistema. 1.2. Comandos at, atd, atq y atrm. El programa at permite lanzar a una determinada hora del día un proceso que nosotros indiquemos. Imaginemos que queremos generar las estadísticas de uso del disco utilizando la instrucción du a las 19:15h, y almacenarlas en el archivo /tmp/du.out. Para ello introduciremos el comando siguiente: # at 19:15 Nos aparecerá un prompt con el formato at> en el que introduciremos el proceso a programar con la salida redireccionada al archivo deseado: at> du –a > /tmp/du.out Por último pulsamos las teclas CTRL+D para dar por finalizado el comando at. Una vez finalizado el comando nos informa por pantalla de que el proceso ha sido programado para que se ejecute a la hora que se había especificado. Una vez planificado el proceso el nuevo trabajo queda almacenado en la cola de trabajos de at, la cual se encuentra en /var/spool/at. En el comando se puede especificar la hora de diferentes maneras: 1. now + <intervalo>: Indica que la ejecución debe ser ahora, más un intérvalo opcional. Si no se especifica el intérvalo significa ahora mismo. La sintaxis para el intervalo es <n> (minutes|hours|days|weeks|months) (minutos|horas|días|semanas|meses – sólo en inglés). Por ejemplo, puede especificar now + 1 hour (dentro de una hora), now + 3 days (dentro de tres días) y así sucesivamente. 2. <hora> <día>: Especificar la fecha por completo. El parámetro <hora> es obligatorio.El comando es muy liberal en lo que acepta, por ejemplo, acepta 0100, 04:20, 2am, 0530pm, 1800, o uno de los tres valores especiales: noon (mediodía), teatime (la hora del té, 16 hs.) o midnight (medianoche). El parámetro <día> es opcional. También puede especificarlo de diferentes maneras: por ejemplo, notación americana para el 20 de diciembre de 2001, 12/20/2001, o europea, 20.12.2001. Puede -ACSO 1- -Página 3 de 22- omitir el año, pero entonces sólo se acepta la notación europea: 20.12.También puede especificar el mes por su abreviatura en inglés: Dec 20 o 20 Dec (ambos válidos). Podemos ahorrar tiempo pasando a at los datos de la programación a través de un fichero pasado como parámetro. Para ello hay que hacer uso del parámetro –f. # at –f nombre_fichero_datos hora_ejecución En cualquier momento podemos examinar los trabajos que se encuentran en cola utilizando el comando atq, y eliminarlos si fuera necesario con la instrucción atrm. Para eliminar un trabajo con atrm es imprescindible conocer el número de trabajo a eliminar, el cual lo podemos averiguar del listado obtenido con atq. Con el programa at también se puede ver la lista de los trabajos programados pasando el parámetro –l (como con atq). # at –l Si a at le pasamos el parámetro –d seguido del número de trabajo programado quitamos ese trabajo de la lista (como con atrm). # at –d <n> Con el parámetro –m envia un mail al usuario cuando el trabajo a finalizado, incluso cuando no hay salida que mostrar. Otro programa interesante es atd, también ejecuta comandos encolados para una ejecución posterior, pero aporta opciones de configuración en función de la carga del sistema. Sus posibles parámetros son: -l Especifica un factor limitador de carga, por encima del cual los trabajos por lotes no deberán ejecutarse, en vez de la elección en tiempo de compilación de 0.8. Para un sistema SMP con n CPUs, probablemente se desee aumentar este índice. -b Especifica el mínimo intervalo en segundos entre el comienzo de dos procesos por lotes (60 por defecto). -d Debug, imprime los mensajes de error a la salida estándar de error en vez de usar syslog. -ACSO 1- -Página 4 de 22- Estos comandos los puede utilizar cualquier usuario. Si por motivos de seguridad se considera oportuno restringir el acceso a at será necesario utilizar los archivos /etc/at.allow y /etc/at.deny. Así, por ejemplo, si queremos que tan sólo los usuarios jaime y marta puedan utilizar el comando at crearemos un archivo /etc/at.allow con el listado de los usuarios (cada usuario en una línea). El aspecto de este archivo sería: jaime marta En el caso de que por defecto tengamos que conceder permisos para utilizar este comando a todos los usuarios menos a los dos mencionados anteriormente emplearíamos el archivo /etc/at.deny. 1.3. Comando batch. La función de este programa es prácticamente la misma que la de at, con la salvedad de que este comando sólo lanzará a ejecución los procesos programados si el nivel de carga del sistema lo permite. El nivel umbral de carga del sistema es 0.8, o el especificado en la invocación de autorun. Las opciones, parámetros y forma de uso es la misma que para at. 1.4. Comandos cron y crontab. El mandato at nos permite un elevado grado de flexibilidad. Es necesario un cierto grado de intervención por parte del usuario para programar las tareas a realizar.Aunque no es un inconveniente para programar pequeños trabajos, esto hace que at no sea adecuado para programar tareas que se repiten regularmente, por ejemplo una copia de seguridad semanal o eliminar cada cierto tiempo los archivos temporales que puedan acumularse en /tmp. En estos casos deberemos emplear cron. Al arrancar el sistema se ejecuta automáticamente un demonio denominado crond. Este demonio se encarga de leer el archivo /etc/crontab y los archivos almacenados en /var/spool/cron. Estos archivos contienen un listado de las diferentes tareas programadas y cuando deben ejecutarse. Las tareas que se programarán con cron se especificarán en un archivo con el siguiente formato: minuto(s) hora(s) día(s) mes(es) díasemana usuario comando argumentos Cada uno de estos campos puede tener los siguientes valores: Campo minuto(s) hora(s) día(s) Mes díasemana -ACSO 1- Valores 0-59 0-23 1-31 1-12 1-7 Descripción Indica el minuto o minutos en los que se ejecutará el comando. Especifica la hora u horas en las que se lanzará el proceso. El día o días del mes en los que se ejecutará la tarea. Ejecuta el mes o meses en los que se ejecutará el comando. Especifica el día o días de la semana en los que se ejecutará la orden. -Página 5 de 22- Cuando se quiere especificar una lista en alguno de los campos los componentes de la lista se separan por comas. Imaginemos que queremos ejecutar una aplicación denominada /bin/limpiar que se encarga de vaciar el directorio /tmp cada minuto 15, 30 y 45 de cada hora del día de cada mes de cada día de la semana. Para ello crearíamos un archivo en nuestro directorio de trabajo, por ejemplo microntab, con el siguiente contenido: 15,30,45 * * * * root /bin/limpiar Una vez guardado el archivo añadiremos los nuevos trabajos a cron utilizando el comando crontab. # crontab microntab En el siguiente ejemplo hemos modificado el archivo anterior para añadir una nueva tarea que se ejecutará cada día 1 del mes a las 23:00. 0 23 1 * * root /bin/comprobar_disco Por último, añadiremos un trabajo que se ejecutará tan sólo los lunes a las 9:00 sea cual sea el mes y día del mes. 0 9 * * 1 root /bin/estadisticas En el último ejemplo lanzaremos un proceso que se ejecutará a las 13:15 el día 15 de cada mes si éste cae en jueves. 15 13 15 * 4 root /bin/formatear Como ya hemos comentado existe un archivo crontab en /etc el cual contiene un conjunto de líneas las cuales se encargan de lanzar los procesos contenidos en los directorios /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly y /etc/cron.monthly. Lanzando el proceso ls –l a estos directorios podemos ver los procesos programados a lanzar cada hora, cada día, cada semana y cada mes. Es posible editar un trabajo de crontab utilizando el comando # crontab –e Como sucedía con el comando at, podemos especificar los usuarios que pueden utilizar crontab con los archivos /etc/cron.allow y /etc/cron.deny. -ACSO 1- -Página 6 de 22- 1.5. Diseño de un shell-script: Automatización de procesos. Se sabe que la descarga de archivos desde ciertos servidores ftp es mucho más rápida a altas horas de la madrugada, por lo que se ha pensado en automatizarlas. Para ello se ha ieado un programa que todos los días de la semana excepto los sábados y los domingos, a las 19:00h pregunte al usuario si quiere realizar una descarga automática de ficheros desde un servidor ftp conocido. Si la respuesta es afirmativa el programa pide los siguientes datos: - Ruta destino de la descarga. Esta ruta debe existir y tener permisos de escritura por parte del usuario para continuar con la ejecución del programa. - Hora de descarga. - Servidor ftp. - Ruta origen absoluta. - Nombre del fichero a descargar. El nombre de usuario a utilizar en la conexión es el mismo que el del propio usuario, y como password se utiliza la palabra del inglés “anonymous”. Una vez introducidos estos datos la “descarga nocturna” queda programada. Pero para que se lance el programa todos los días a la 19:00h hay que hacer algo más. Concretamente se ha diseñado un programa para la automatización de procesos. Cuando se quiere automatizar un nuevo proceso se lanza este programa, el cual pide: - Minuto o lista de minutos en los que se ejecutará el comando. - Hora o lista de horas en las que se ejecutará el programa. - Día i lista de días del mes en los que se ejecutará el programa. - Mes o lista de meses en los que se ejecutará el programa. - Día o días de la semana en los que se ejecutará el programa. - Procesos a ejecutar (con su ruta absoluta). Este programa crea un fichero con todos los datos y automatiza la ejecución del primer programa (o el que se quiera automatizar). Ambos programas se entregan en los archivos adjuntos a este trabajo. 2. ADMINISTRACIÓN DE PROCESOS EN UNIX. 2.1. Introducción. Al arrancar un sistema UNIX se ejecutan automáticamente un conjunto de aplicaciones y demonios. Cuando estas aplicaciones, o aquellos programas lanzados por el usuario, se ejecutan se carga una instancia de los mismos en memoria, convirtiéndose en ese momento en un proceso en ejecución en el sistema. Un proceso utiliza un determinado conjunto de recursos del ordenador como son tiempo de CPU, memoria física y virtual, disco, ... para realizar la tarea que le haya sido asignada. Como los procesos consumen recursos del sistema son un aspecto importante a controlar para obtener un óptimo rendimiento del ordenador. -ACSO 1- -Página 7 de 22- 2.2. Como se inicia un proceso. El proceso de arranque de UNIX es en cierta forma parecido al proceso de arranque de cualquier sistema operativo. Al poner en marcha el ordenador éste buscará en los discos de inicio una pequeña aplicación que se encargará de cargar el kernel del sistema operativo. Una vez cargado el kernel éste se ocupará de ejecutar los demonios y aplicaciones configuradas para cargarse al iniciarse el sistema. A cada uno de estos procesos se les asigna un número denominado PID (Process IDentification), empleándose este número para manipular los procesos en ejecución. Por ejemplo, INIT es un proceso cuyas funciones son: arranque del sistema, tareas de limpieza, matar los procesos durante el proceso de apagado del sistema. Su PID es 1, es el padre de todos los procesos del sistema. 2.3. Monitorización de procesos. 2.3.1. Monitorizar procesos desde el entorno de ventanas. UNIX pone a nuestra disposición un conjunto de herramientas que podemos emplear para monitorizar y controlar los procesos en ejecución. La mayoria de los comandos se utilizan desde la línea de comandos, aunque existen aplicaciones equivalentes que pueden emplearse desde el entorno gráfico, como gTop, o de forma remota con un navegador, como Webmin. Estos programas se pueden ejecutar desde el entorno de ventanas o desde la línea de comandos introduciendo su nombre. Por ejemplo, si queremos ejecutar gTop desde la línea de comandos: # gTop Aparece una ventana con todos los procesos en ejecución y las características de los mismos. En los menús desplegables están todas las posibles acciones que se pueden realizar sobre los procesos. NOTA: En los ordenadores del laboratorio de Arquitectura de Computadores no están instaladas estas utilidades 2.3.2. Monitorizar el estado de los procesos: ps. Con el comando ps obtenemos información de los procesos en ejecución. Al ejecutar este comando desde el shell obtendremos un listado con los procesos en ejecución del usuario. # ps Esta instucción visualiza la lista de los procesos del usuario de forma tabular. A continuación se detalla el significado de todas las columnas que pueden aparecer al emplear el comando. Columna -ACSO 1- Descripción -Página 8 de 22- USER o UID Usuario propietario del proceso. PID Número identificador del proceso. %CPU Porcentaje de utilización de la CPU. Debido a la forma en que se calcula este porcentaje es posible que en determinadas circunstancias exceda el 100%. %MEM Porcentaje de memoria utilizado por el proceso. SIZE Tamaño en kbytes de memoria virtual empleada por el proceso. RSS Tamaño de memoria residente en kbytes utilizada por el proceso. TTY Terminal al que se encuentra asociado el proceso. STAT Estado actual del proceso. El estado se representa por una letra en mayúsculas. Algunos de los posibles valores son: Letra Descripción R Run, el proceso se encuentra en ejecución. S Sleeping, el proceso está en espera. I Idle, el proceso está inactivo. D Disk wait, en espera de una operación de disco. P Page wait, en espera de una operación de paginación. W Swapped out. N Su prioridad ha sido bajada utilizando el comando nice. T Terminated, el proceso ha sido finalizado. < La prioridad de ejecución ha sido subida por un superusuario. START Fecha u hora en que se inició la ejecución del proceso. COMMAND Shell en ejecución. NI Prioridad establecida por el comando nice. PRI Nivel de prioridad del proceso. PPID Especifica el PID del proceso padre. WCHAN Nombre de la función del kernel donde el proceso está en reposo. FLAGS Flag asociado al proceso. La información obtenido por defecto con el comando ps es mínima. Para obtener más información debemos hacer uso de diferentes parámetros. Parámetros Descripción a Visualiza los procesos de todos los usuarios. e Visualiza las variables de entorno de los procesos. l Visualiza la máxima información posible. u Visualiza el nombre de usuario y la hora de inicio del proceso. W Visualiza el resultado en formato ancho. Si la salida por pantalla no cabe en una línea ésta no quedará cortada. -ACSO 1- -Página 9 de 22- txx Visualiza los procesos asociándose con el terminal tty especificado por x. x Visualiza los procesos sin controlar por tty. Para ver el usuario y hora de inicio de los procesos utilzaremos el parámetro u. # ps u Para obtener los procesos en ejecución y sus variables de entorno utilizamos el parámetro e. # ps e Si trabajamos como usuario root y queremos ver todos los procesos en ejecución de un determinado usuario podemos combinar los comando ps y grep de ls siguiente forma: # ps –A au | grep nombre_de_usuario En el caso de que el listado fuera muy largo, lo combinaríamos con more o less para realizar pausas cada vez que se llene la pantalla. # ps –A au | grep nombre_de_usuario | more Algunas veces será necesario averiguar el proceso padre desde el que se ejecutó un determinado proceso, para ello utilizaremos el comando ps con el siguiente formato: # ps | PID Donde PID es el número del proceso hijo. 2.4. Control de procesos. Todo sistema operativo tipo UNIX proporciona un conjunto estándar de herramientas empleadas para controlar la ejecución de los procesos, permitiéndonos detener temporalmente un proceso, cambiar su prioridad de ejecución o simplemente finalizar la ejecución. 2.4.1. Cambiar la prioridad de los procesos: nice y renice. Para optimizar el rendimiento de un proceso determinado puede ser necesario cambiar su prioridad en la cola de procesos para asignarle de esta forma más tiempo de procesador o quitarle tiempo de procesador en el caso de que sea una tarea poco importante. El comando que utilizaremos para cambiar la prioridad de un proceso es nice, siendo el rango de valores válidos desde –20 hasta 20, donde –20 es la prioridad máxima y 20 la mínima. # nice –10 mi_ejemplo.pl -ACSO 1- -Página 10 de 22- Si no se añaden argumentos, nice imprime la prioridad de planificación actual. De otra modo, ejecuta el comando dado con la prioridad de planificacin ajustada. Si no se añade un ajuste, la prioridad del comando es incrementada en 10. Para realizar esta tarea también podemos emplear el comando renice, que altera la prioridad de planificación de uno o más procesos en ejecución. Los siguientes parámetros son interpretados como ID's de proceso, ID's de grupo de proceso, o nombres de usuario. Aplicar renice a un grupo de procesos provoca que todos los procesos del grupo de procesos vean alterada su prioridad de planificacin. Aplicar renice a un usuario hace que todos sus procesos vean la prioridad de planificación alterada. Por defecto, los procesos se especifican a partir de su ID de proceso. Las opciones soportadas por renice son: -g -u -p Forzar que los parámetros sean interpretados como ID's de grupo de proceso. Forzar que los parámetros sean interpretados como nombres de usuario. Reinicia la interpretación de los parámetros para que sea la de ID de proceso (por defecto). Por ejemplo, renice +1 987 -u daemon root -p 32 cambiara la prioridad de los procesos con ID 987 y 32, y todos los procesos de los usuarios daemon y root a un valor igual a +1. # renice –5 1145 Cambia la prioridad del proceso cuyo PID es 1145 a un valor de nice igual a –5. Cada usuario, excepto el superusuario, sólo podrá alterar la prioridad de sus procesos y sólo podrá incrementar su valor nice entre el rango 0 y +20. El superusuario podrá modificar la prioridad de cualquier proceso y poner la prioridad en cualquier valor. Prioridades útiles son: +20 0 -n los procesos afectados solo corren cuando ningún otro lo desee en el sistema, la prioridad de planificación base. cualquier valor negativo para acelerar el proceso. Los usuarios normales no pueden incrementar la prioridad de sus procesos, aunque la decrementaran ellos mismos con anterioridad. 2.4.2. Matar procesos: kill. -ACSO 1- -Página 11 de 22- El comando kill nos va a permitir manipular la ejecución de un proceso. Para ver las diferentes opciones de kill ejecutaremos el comando: # kill –l Las posibles opciones de este comando son las siguientes: Opción 1 Nombre SIGHUP 2 3 4 5 6 7 8 9 SIGINT SIGQUIT SIGILL SIGTRAP SIGIOT SIGBUS SGFPE SIGKILL 10 11 12 13 14 15 SIGUSR1 SIGSEGV SIGUSR2 SIGPIPE SIGALRM SIGTERM 16 17 18 SIGTKFLT SIGCHLD SIGCONT 19 20 21 SIGSTOP SIGTSTP SIGTTIN 22 SIGTTOU 23 24 25 26 27 28 29 30 31 SIGURG SIGXCPU SIGXFSZ SIGVTALRM SIGPROF SIGWINCH SIGIO SIGPWR UNUSED Descripción Indica a un proceso que vuelva a cargar los archivos de configuración. Interrumpir. Salir. Instrucción ilegal. Rastrear trap. Instrucción IOT. Error de bus. Excepción de coma flotante. Matar un proceso. Esta señal no puede ser ignorada por ningún proceso. Señal definida por el usuario número 1. Violación de segmentación. Señal definida por el usuario número 2. Escritura en una tuberia (PIPE). Alarma de reloj. Señal de finalización. Usualmente se envia antes de SIGKILL, permitiendo al proceso prepararse para finalizarse. Fallo en la pila del coprocesador. El estado del proceso hijo ha cambiado. Continuar después de una señal SIGSTOP. Esta señal no puede bloquearse. Detener el proceso. Detener una señal generada por el teclado. Intento de lectura en segundo plano desde el terminal de control. Intento de escritura en segundo plano al terminal de control. Advertencia urgente en el socket. Tiempo de CPU excedido. Excedido tamaño límite del archivo. Alarma virtual de tiempo. Perfil de la alarma de contador. Se ha cambiado el tamaño de la ventana. Es posible la E/S en el descriptor Fallo de alimentación. Sin usar. Por ejemplo, si queremos matar un proceso ejecutaremos: -ACSO 1- -Página 12 de 22- # kill –9 PID Antes de enviar esta señal conviene enviarle otra señal al proceso para permitirle prepararse para finalizarse: # kill –15 PID Para probar la diferentes opciones del kill hemos desarrollado un programa el Perl que genera toda la lista de señales del sistema. Lo primero que debemos hacer es ejecutar este programa redireccionando la salida a un fichero. # perl generar_ejemplo_procesos.pl > mi_ejemplo.pl En el archivo mi_ejemplo.pl tendremos una lista con todas las señales del sistema. Ahora ejecutamos el programa que hemos creado. # perl mi_ejemplo.pl Ahora podemos, desde otro terminal, ejecutar el comando kill y ver el resultado que produce. El programa se entrega en el diskette adjunto a esta memoria. 2.4.3. Ejecución de procesos en segundo plano. Normalmente, cuando ejecutamos un programa desde la línea de comandos el proceso se ejecuta en primer plano lo que nos obliga a esperar a que este termine para realizar otrar tareas (a no ser que abramos otro terminal). Unix nos permite ejecutar programas en segundo plano. De esta forma podemos seguir trabajando en la línea de comandos sin tener que esperar a que el proceso finalice. Para ejecutar un proceso en segundo plano será necesario añadir el carácter & al final del comando. # ls –l /etc >tmp/listado.out & Si el programa creado en el apartado anterior lo hubieramos ejecutado en segundo plano no hubiera hecho falta abrir otro terminal para probar el comando kill. #perl mi_ejemplo.pl & La ejecución de un programa en segundo plano no impide que aparezcan en la pantalla los mensajes de error que se produzcan (a no ser que se haya redirigido la salida de errores), y que el programa se pare cuando se salga del sistema. Para que el programa continúe ejecutándose aún cuando nosotros hayamos terminado la sesión, hay que utilizar el comando nohup. # nohup program -ACSO 1- -Página 13 de 22- Si no se utilizan redirecciones todas las salidas del programa se dirigen a un fichero llamado nohup.out. Cuando se utiliza nohup el ordenador entiende que el usuario no tiene prisa y automáticamente disminuye la prioridad de la ejecución. 2.5. Monitorización del sistema. Los comandos de esta sección son de utilidad a la hora de mostrar las estadísticas del sistema operativo o de parte de él 2.5.1. Monitorizar la cantidad de espacio en disco: du y df. Los usuarios disponen de una cuota de disco duro limitada, para monitorizar las cuotas de disco de usuario se utiliza el programa quota. # quota A este programa se le puede sacar un mayor rendimiento pasándole alguno de los siguientes parámetros: -g -q -v Informa de la quota del grupo del usuario. Aporta información sobre el sistema de archivos en los que su uso está por encima del límite. Informa sobre las cuotas de un disco remoto. Los usuarios sólo pueden hacer uso del primer parámetro. El resto de parámetros sólo los puede referenciar el superusuario. Para ver el espacio de disco ocupado se utiliza el comando du (Disk Used). # du Este comando permite conocer el espacio ocupado en el disco por un determinado directorio y todos los subdirectorios que cuelgan de él. Un posible salida de este comando sería la siguiente: 22 508 204 ./src ./bin . Esta salida indica que el directorio ./src ocupa 22 bloques, el ./bin ocupa 508 bloques y el directorio activo, ".", ocupa 204 bloques. El bloque es la unidad de almacenamiento en disco y depende del sistema; en GNU es igual a 1024bytes (1 kbyte). -ACSO 1- -Página 14 de 22- Debe notarse que esta salida lista el espacio usado por el directorio activo y por todos sus subdirectorios. Si queremos ver el espacio de disco ocupado por un fichero o un directorio debemos pasar el nombre del fichero o directorio en cuestión como argumento. También se le puede pasar una lista de ficheros o directorios. # du nombre_de_fichero La unidad de medida es en bloques, para obtener la información en bytes se debe emplear el comando con la opción –b. # du –b Si queremos que la medida sea en kbytes utilizaremos el parámetro –k (en GNU por defecto la medida es en kbytes). # du -k 1162 4313 ./dos.ver . En este ejemplo tenemos el espacio en kbytes ocupado por el directorio activo (.), y por el subdirectorio hijo del directorio activo (dos.ver). Si por el contrario queremos que la medida sea en megabytes utilizaremos el parámetro –m. # du –m 1 4 ./dos.ver . El parámetro –s imprime solamente el espacio ocupado por el directorio actual o el pasado como parámetro, evitando sacar información de los subdirectorios del mismo. # du –s Sguiendo con el ejemplo anterior la salida sería: 204 . Otros parámetros interesantes son: -h -S -ACSO 1- Añade una letra indicativa del tamaño, como M para megabytes, a cada tamaño. Informa del tamaño de cada directorio separadamente, sin incluir los tamaños de los subdirectorios. -Página 15 de 22- -c –a Muestra un total para todos los argumentos después de que éstos se hayan procesado. Esto puede emplearse para encontrar el uso de disco total de un conjunto dado de ficheros o directorios. Muestra además del espacio ocupado por los subdirectorios, el de los ficheros del directorio de trabajo. El comando df (Disk Free) por el contrario resume la cantidad de espacio utilizada en el disco. # df Esta instrucción muestra, para cada sistema de ficheros, el espacio total de disco, la cantidad utilizada, la cantidad disponible, y la capacidad total del sistema de ficheros que se utiliza. Un caso extraño que puede darse es la posibilidad de tener una capacidad superior al 100%, o que la cantidad utilizada más la disponible no sea igual a la total. Esto es debido a que Unix reserva parte del espacio de cada sistema de ficheros para el directorio raiz. De esta forma aunque algún usuario accidentalmente sature el disco, el sistema todavía tendrá un poco de espacio para el sistema operativo. Podemos pasar como argumento el nombre concreto de un fichero o un directorio. Si no se pasa ningún fichero toma por defecto el directorio actual. Una posible salida de este programa es la siguiente: Filesystem /dev/hda1 /dev/hda2 /dev/hdb1 1024-blocks 195167 2783807 2039559 Used 43405 688916 1675652 Available 141684 1950949 258472 Capacity 23% 26% 87% Mounted on / /usr /home/webb La información que aporta cada una de las columnas es la siguiente: nombre del dispositivo en el sistema, la capacidad total del dispositivo, la cantidad usada, la cantidad libre, el porcentaje de ocupación, y la ruta en la que el dispositivo está montado. Podemos ahorrar espacio en disco haciendo uso de los llamados enlaces (links). Un enlace permite el uso de un fichero en otro directorio distinto del original sin necesidad de copiarlo, con el consiguiente ahorro de espacio. El programa ln permite realizar un enlace entre dos ficheros o directorios. Un enlace puede ser: • Hard link: se puede realizar sólo entre ficheros del mismo sistema de ficheros. El fichero enlazado apunta a la zona de disco donde se halla el fichero original. Por tanto, si se elimina el fichero original, el enlace sigue teniendo acceso a dicha información. Es el enlace por omisión. -ACSO 1- -Página 16 de 22- • Symbolic link: permite enlazar ficheros/directorios de diferentes sistemas de ficheros. El fichero enlazado apunta al nombre del original. Así si se elimina el fichero original el enlace apunta hacia un nombre sin información asociada. Para realizar este tipo de enlace debe emplearse la opción –s. 2.5.2. Monitorizar el estado de memoria: free. Este comando muestra la cantidad total de memoria física y de intercambio presente en el sistema, así como la memoria compartida y los buffers usados por el nucleo. Existe un conjunto de modificadores de esta instrucción: • • • • • • El modificador –b muestra la cantidad de memoria en bytes El modificador –k (puesto por defecto) la muestra en kilobytes El modificador –m la muestra en megabytes. El modificador –t muestra en una linea los totales. El modificador –o desactiva el mostrar la linea de "ajuste de buffer". El modificador –s activa el refresco de la informacion cada n segundos. Es posible especificar cualquier numero en coma flotante para n. 2.5.3. Monitorizar la carga del sistema: top y time. En cualquier sistema operativo es importante poder monitorizar el estado del ordenador y la carga de procesos existente. Unix pone a nuestra disposición diversas herramientas para realizar esta tarea, siendo quizás la más empleada el comando top. Este comando visualiza el listado con la actividad del sistema especificando el tiempo de procesador de cada tarea, uso de memoria, número de procesos, etc. # top top proporciona una visión continuada de la actividad del procesador en tiempo real. Muestra un listado de las tareas que hacen un uso más intensivo de la CPU en el sistema, y puede proporcionar una interfaz interactiva para manipular procesos. Puede clasificar las tareas por empleo de CPU, uso de memoria y tiempo de ejecución. La mayora de las características pueden seleccionarse mediante una orden interactiva o especificándola en el fichero de configuración personal o general Parametros: d Especifica el intervalo entre actualizaciones de la pantalla. Esto puede cambiarse con la orden interactiva s. -ACSO 1- -Página 17 de 22- q S s i c Esto hace que top redibuje la pantalla sin intervalo ninguno. Si el que ejecuta el programa tiene privilegios de sperusuario, top se ejecuta con la prioridad más alta posible. Especifica el modo acumulativo, donde cada proceso se lista con el tiempo de CPU que ha gastado. Esto es como la opción -S de ps. Le dice a top que se ejecute en modo seguro. Esto inhabilita el peligro potencial de las órdenes interactivas Arranca top descartando cualquier proceso inactivo o zombie. Muestra la línea de órdenes entera en lugar de solamente el nombre de la orden. El comportamiento predeterminado se ha cambiado puesto que esto parece ser de más utilidad. Lectura de los campos: Uptime. Processes. CPU states. Mem. Swap. PID. PPID. UID. USER. PRI. NI. SIZE. TSIZE. DSIZE. TRS. SWAP. D. LIB. -ACSO 1- Esta lnea muestra el tiempo que el sistema ha estado activo, y las tres medias de carga para el sistema. Las medias de carga son el número medio de procesos listos para ejecutarse durante los ltimos 1, 5 y 15 minutos. Esta línea es simplemente como la salida de uptime. La línea de uptime puede quitarse o ponerse con la orden interactiva ll (ele minscula). El número total de procesos ejecutándose. Las líneas de procesos y estados pueden quitarse o ponerse con la orden interactiva t. Muestra el porcentaje de tiempo de CPU en modo de usuario, en modo de sistema , en tareas con la prioridad alterada por nice, y el tiempo de inactividad. Las tareas con la prioridad alterada por nice son solamente aqullas cuyo valor nice es negativo. El tiempo transcurrido en las tareas con la prioridad alterada por nice también se contará en el tiempo de sistema y de usuario, por lo que el total puede ser superior al 100%. Las líneas de procesos y estados y tiempos de CPU pueden quitarse o ponerse con la orden interactiva t. Datos sobre el empleo de memoria, incluyendo la memoria disponible en total, la memoria libre, la usada, la compartida, y la utilizada para búferes. La línea de la información de memoria puede ponerse o quitarse con la orden interactiva m. Datos sobre el espacio de trasiego, incluyendo el total, el disponible y el empleado. Esto y Mem son sencillamente como la salida de free. El identificador (ID) de proceso (PID) de cada tarea. El ID del proceso padre de cada tarea. El ID de usuario del propietario de la tarea. El nombre de usuario del propietario de la tarea. La prioridad de la tarea. El valor de nice de la tarea. Valores negativos indican menor prioridad. Se muestra aquí el tamaño del código de la tarea más datos más espacio de pila, en kB. El tamaño del texto o código de la tarea. Esta da valores extraños para procesos del núcleo. Tamao de Datos + Pila. Tamaño del texto (código) residente. Tamaño de la parte de la tarea que está en el espacio de trasiego. Tamaño de las páginas marcadas como sucias. Tamaño de las páginas de biblioteca usadas. -Página 18 de 22- RSS. Se muestra la cantidad total de memoria física utilizada por la tarea, en kilobytes. SHARE. Se muestra en esta columna la cantidad de memoria compartida empleada por la tarea. STAT. Aquí se ve el estado de la tarea. El estado puede ser S para durmiente, D para sueño no interrumpible, R para ejecución, Z para zombies, o T para parados o trazados. TIME. El tiempo total de CPU que la tarea ha usado desde que empezó . Si el modo acumulativo est activado, también incluye el tiempo de CPU empleado por los hijos del proceso que hayan muerto. Uno puede establecer el modo acumulativo con la opción de la línea de órdenes S o cambiarlo con la orden interactiva S. %CPU. La porción del tiempo de CPU consumido por la tarea desde la ltima actualización de la pantalla, expresada como un porcentaje del tiempo de CPU total. %MEM. La porción de la memoria física ocupada por la tarea. COMMAND. El nombre de la orden de la tarea, que se truncar si es demasiado largo como para mostrarse en una línea. Existen diversos equivalentes a este comando que pueden utilizarse desde el entorno gráfico como es el caso de gtop. Esta aplicación muestra más estadísticas a parte de las visualizadas por top, permitiendonos además realizar operaciones típicas de los comandos kill y nice. Otra herramienta que también podemos utilizar para obtener información del estado del sistema es vmstat, la cual nos informa del estado de los procesos y memoria. # vmstat Para obtener unas estadísticas rápidas del estado del sistema emplearemos el comando uptime. # uptime El comando uptime informa sobre el tiempo en el que el sistema ha estado activo, es decir el tiempo transcurrido desde que Unix arrancó por última vez. Este comando también devuelve la hora actual y el promedio de carga que ha soportado el sistema durate el último minuto y los cinco y diez últimos minutos. El promedio de carga es el número medio de procesos esperando a ejecutar en un determinado periodo de tiempo. Si este promedio de carga se aproxima a cero indica que el sistema ha estado relativamente desocupado; por el contrario si el promedio es cercano al uno indica que el sistema ha estado casi completamente utilizado pero en ningún momento sobrecargado. Los promedios de carga altos son el resultado de la ejecución simultánea de varios programas. Es uno de los pocos comandos de Unix que no tienen opciones. -ACSO 1- -Página 19 de 22- Otro programa interesante es w, devuelve los usuarios actuales del sistema y qué están haciendo. #w Básicamente combina la funcionalidad de uptime y who. La cabecera del informe que presenta w es exactamente la misma que uptime, siendo la información de cada una de las líneas la siguiente: el nombre del usuario, hora de inicio de la sesión (y cuanto tiempo ha estado ocioso), JCPU es la cantidad total de tiempo de CPU utilizada por ese usuario, mientras que PCPU es la cantidad total de tiempo utilizada por sus tareas actuales. Si al comando se le pasa la opción –f, mostrará los sistemas remotos desde los que los usuarios acceden, si los hay. # w –f Puede indicarse un nombre de usuario como parámetro para mostrar sólo información relativa a él. # w –f nombre_de_usuario El comando time, precediendo a cualquier otro comando, suministra información acerca del tiempo total empleado en la ejecución, del tiempo de CPU utilizado por el programa del usuario, y del tiempo de CPU consumido en utilizar recursos del sistema. Por ejemplo para saber el tiempo utilizado en la compilación y montaje del programa prueba.c utilizaríamos el comando # time gcc prueba.c 2.6. Diseño de un shell-script: Control de la carga del sistema. Se ha diseñado un programa que evalua la carga del sistema y, si supera uno de los umbrales definidos en consumo de cpu, memoria o disco duro, se busca el proceso y el dueño del mismo, y a dicho proceso bien se le cambia el factor de prioridad, bien se pausa, o incluso se mata en función del consumo de recursos que tiene. Los umbrales quedan definidos en el programa. El archivoes “control_de_procesos”. -ACSO 1- -Página 20 de 22- 3. DESCARGA AUTOMATICA DE ARCHIVOS CON CONTROL DE CARGA DEL SISTEMA. Este shell script está basado en los scripts diseñados anteriormente. Sobre el primer shellscript para la descarga automática de ficheros desde un servidor ftp conocido se le ha hecho una modificación para que sólo realice la descarga nocturna si el disco duro no está muy saturado. Una vez programada la descarga nocturna hay que programar para la misma hora la ejecución del programa para el control de carga del sistema, modificando este último para que se base en el control de la descarga nocturna, pasando por alto el consumo del resto de procesos. Todo esto se auna en un shell-script. JUSTIFICACIÓN Este trabajo se ha realizado como ampliación a las prácticas realizadas en el laboratorio, pudiendo utilizarse si se cree conveniente como “práctica voluntaria” en años sucesivos. En todo momento se han intentado dar ejemplos y comparaciones con un sistema que existe y es utilizado actualmente por varias empresas dedicadas al cable, proponiéndose una posible extensión de este trabajo para la automatización de las tareas de mantenimiento de un sistema de acceso condicional basado en UNIX. BIBLIOGRAFÍA • El Entorno de Programación Unix. Fernando Bellas Permuy. Departamento de • • • • • • Tecnologías de la Información y las Comunicaciones (TIC). Universidad de A Coruña. El Sistema Operativo Unix. Departamento de Ingeniería de Sistemas y Automática. Universidad de Valladolid. Guía de Linux Para el Usuario. Larry Greenfield. Aprenda LINUX como si estuviera en primero. Javier García de Jalón. Escuela Superior de Ingenieros Industriales de San Sebastián. Universidad de Navarra. Guía de Usuario Mandrake. Advanced Linux Programming. LINUX a fondo. Albert Bernaus, Jaime Blanco. Infor Books. PROPUESTA DE PUNTUACIÓN Y FECHA LÍMITE DE ENTREGA Este trabajo se divide en 4 apartados que, por su diferente complejidad propongo se puntuen de la siguiente manera: Primer apartado – 0.7 puntos Segundo apartado – 0.7 puntos Tercer apartado – 0.35 puntos -ACSO 1- -Página 21 de 22- --------------------------------------------TOTAL – 1.75 puntos FECHA LÍMITE DE ENTRAGA: 31 DE ENERO DE 2003 -ACSO 1- -Página 22 de 22-