9 managing processes

59
Managing Processes 1 Capítulo 1 Introducción a Procesos Conceptos clave Un proceso es una instancia de un ejecutable en ejecución identificado por un id de proceso (pid). Debido a que Linux implementa memoria virtual cada proceso posee su propio contexto distintivo de memoria. Un proceso tiene un uid y una colección de gid como credenciales. Un proceso tiene un contexto de sistema de archivos incluyendo un cwd, una umask, un directorio raíz y una colección de archivos abiertos. Un proceso tiene un contexto de programación que incluye un valor de niceness. Un proceso tiene una colección de variables de entorno. El comando ps puede utilizarse para examinar todos los procesos actuales en ejecución. El comando top puede utilizarse para controlar todos los procesos en ejecución. Los procesos tienen que ver con el cómo se hacen las cosas Casi cualquier cosa que suceda en un sistema Linux tiene lugar como un proceso. Si usted está viendo este texto en un navegador, ese navegador se está ejecutando como un proceso. Si está tecleando en una línea de comandos de la shell bash, esa shell está ejecutando como un proceso. Si está utilizando el comando chmod para cambiar un permiso de un archivo, el comando chmod funciona como un proceso por separado. Los procesos tienen que ver con el cómo se consigue hacer las cosas y la responsabilidad principal del kernel de Linux es proporcionar un lugar para que los procesos ejerzan su labor sin necesidad de tocar el campo del otro. Los procesos son una instancia de un programa en funcionamiento. En otros sistemas operativos los programas suelen ser grandes y elaboradas aplicaciones gráficas que se toman una gran cantidad de tiempo para iniciar. En el mundo de Linux (y Unix), estos tipos de programas también existen, al igual que toda una clase de programas que usualmente no tienen una contraparte en los sistemas operativos. Estos programas están diseñados para iniciar rápidamente, especializados en funciones y trabajan bien con otros programas. En un sistema de Linux, los procesos que ejecutan estos programas están constantemente apareciendo y desapareciendo. Por ejemplo, considere que el usuario maxwell escribe la siguiente línea de comandos. [maxwell@station maxwell]$ ps aux | grep httpd > daemons.$(date +%d%b%y) En una fracción de segundo que la línea de comandos utilizó para ejecutar, no menos de cuatro procesos (ps, grep, bash y date) se iniciaron, hicieron lo que tenían que hacer y salieron. ¿Qué es un proceso?

Transcript of 9 managing processes

Managing Processes

1

Capítulo 1 Introducción a Procesos

Conceptos clave

• Un proceso es una instancia de un ejecutable en ejecución identificado por un id de proceso (pid).

• Debido a que Linux implementa memoria virtual cada proceso posee su propio contexto distintivo de memoria.

• Un proceso tiene un uid y una colección de gid como credenciales. • Un proceso tiene un contexto de sistema de archivos incluyendo un cwd, una

umask, un directorio raíz y una colección de archivos abiertos. • Un proceso tiene un contexto de programación que incluye un valor de niceness. • Un proceso tiene una colección de variables de entorno. • El comando ps puede utilizarse para examinar todos los procesos actuales en

ejecución. • El comando top puede utilizarse para controlar todos los procesos en ejecución.

Los procesos tienen que ver con el cómo se hacen las cosas

Casi cualquier cosa que suceda en un sistema Linux tiene lugar como un proceso. Si usted está viendo este texto en un navegador, ese navegador se está ejecutando como un proceso. Si está tecleando en una línea de comandos de la shell bash, esa shell está ejecutando como un proceso. Si está utilizando el comando chmod para cambiar un permiso de un archivo, el comando chmod funciona como un proceso por separado. Los procesos tienen que ver con el cómo se consigue hacer las cosas y la responsabilidad principal del kernel de Linux es proporcionar un lugar para que los procesos ejerzan su labor sin necesidad de tocar el campo del otro.

Los procesos son una instancia de un programa en funcionamiento. En otros sistemas operativos los programas suelen ser grandes y elaboradas aplicaciones gráficas que se toman una gran cantidad de tiempo para iniciar. En el mundo de Linux (y Unix), estos tipos de programas también existen, al igual que toda una clase de programas que usualmente no tienen una contraparte en los sistemas operativos. Estos programas están diseñados para iniciar rápidamente, especializados en funciones y trabajan bien con otros programas. En un sistema de Linux, los procesos que ejecutan estos programas están constantemente apareciendo y desapareciendo. Por ejemplo, considere que el usuario maxwell escribe la siguiente línea de comandos.

[maxwell@station maxwell]$ ps aux | grep httpd > daemons.$(date +%d%b%y)

En una fracción de segundo que la línea de comandos utilizó para ejecutar, no menos de cuatro procesos (ps, grep, bash y date) se iniciaron, hicieron lo que tenían que hacer y salieron.

¿Qué es un proceso?

Managing Processes

2

En este momento ya estará cansado de escuchar la misma pregunta: un proceso en una instancia de un programa en ejecución. No obstante, aquí ofrecemos una lista detallada de componentes que constituyen un proceso.

Contexto de ejecución

Cada proceso existe (al menos hasta cierto punto) dentro de una memoria física de la máquina. Puesto que Linux (y Unix) están diseñados para ser un entorno multiusuario, la memoria asignada a un proceso está protegida y ningún otro proceso puede acceder a ésta. Un proceso carga en su memoria una copia de las instrucciones ejecutables y almacena cualquier otra información dinámica que esté manejando. Un proceso también lleva parámetros asociados con la frecuencia de acceso que se tiene a la CPU, tales como su estado de ejecución y su valor de niceness (pronto hablaremos más en detalle sobre esto).

Contexto de E/S

Cada proceso interactúa hasta cierto punto con el sistema de archivos para leer y escribir información que existe o existirá después del ciclo de vida del proceso. Los elementos de entrada y salida (E/S) de un proceso incluyen lo siguiente:

Descriptores de archivo abierto

Casi todos los procesos suelen leer información de o escribir información a fuentes externas. En Linux, los descriptores de archivos abiertos actúan como fuentes o receptores de información. Los procesos leen información de o escriben información a los descriptores de archivos abiertos que pueden estar conectados a archivos regulares, nodos de dispositivos, conexiones de red o incluso entre sí como tuberías (permitiendo la comunicación entre procesos).

Archivos de trazado de memoria

Los archivos de trazado de memoria son los archivos cuyo contenido se ha trazado directamente en la memoria del proceso. En lugar de leer o escribir en un descriptor de archivo, el proceso sólo accede a la dirección de memoria apropiada. Los mapas de memoria suelen utilizarse para cargar el código ejecutable, pero también sirven para otros tipos de acceso no secuencial a los datos.

Contexto del sistema de archivos

Hemos encontrado varias partes de información relacionadas con el sistema de archivos que mantiene los procesos, tales como el directorio de trabajo actual del proceso (para traducir referencias de archivos) y la umask del proceso (para establecer permisos en archivos recién creados). [1]

Variables de entorno

Managing Processes

3

Cada proceso mantiene su propia lista de pares nombre-valor, conocida como variables de entorno o en general como el entorno del proceso. Los procesos por lo general heredan su entorno en el inicio y pueden referirse a éste para obtener datos tales como el lenguaje preferido o el editor favorito del usuario.

Información de herencia

Cada proceso se identifica con un PID o id del proceso asignado en el momento de su creación. En una próxima lección, veremos que cada proceso tiene claramente definido un padre y posiblemente unos hijos también. La identidad del propio proceso, la identidad de sus hijos y hasta cierto punto la identidad de sus hermanos son mantenidos por el proceso.

Credenciales

Cada proceso se ejecuta bajo el contexto de un determinado usuario (o más exactamente de un id de usuario determinado) y bajo el contexto de una colección de id de grupo (generalmente, todos los grupos a los que pertenezca el usuario). Estas credenciales limitan los recursos a los que el proceso puede acceder tales como qué archivos pueden abrir o con qué otros procesos se les permite comunicarse.

Estadísticas de recursos y límites

Cada proceso también registra estadísticas para trazar la cantidad de recursos del sistema utilizados, el número de archivos abiertos, la cantidad de tiempo de CPU, etc. La cantidad de recursos que se le permite utilizar a un proceso también puede limitarse con un concepto llamado límite de recursos.

Ver procesos con el comando ps

Ya hemos visto varias veces el comando ps. Ahora, trataremos de familiarizarnos con una selección más amplia de opciones asociadas a éste. Una ejecución rápida de ps --help mostrará un resumen de más de 50 opciones diferentes para personalizar la conducta del comando ps. las cosas se complican un poco porque diferentes versiones de Linux han desarrollado sus propias versiones del comando ps, las cuales no utilizan las mismas convenciones para las opciones. La versión de Linux del comando ps trata de acomodarse a diferentes versiones anteriores de Unix y suele haber opciones múltiples para cualquier opción determinada, algunas de las cuales comienzan con un guión inicial (“- ”).

Selección de procesos

De forma predeterminada, el comando ps lista todos los procesos iniciados desde una terminal de usuario. Aunque esta conducta es razonable, cuando los usuarios están conectados a cajas de UNIX con terminales seriales de línea, parece un poco simplista cuando cada ventana de una terminal dentro de un entorno gráfico X se trata como una

Managing Processes

4

terminal independiente. Los siguientes modificadores de línea de comandos pueden utilizarse para expandir (o reducir) los procesos listados por el comando ps .

Table 1. Opciones comunes del comando ps para la selección de procesos

Opción Procesos listados

-A, -e, ax Todos los procesos.

-C command Todas las instancias de command

-U, --user, --User user Todos los procesos que pertenecen a user

-t, --tty terminal Todos los procesos iniciados desde terminal

-p, p, --pid N Procesos con pid N

Selección de salida

Como se deduce de los párrafos iniciales de esta lección hay muchos parámetros asociados con procesos, demasiados para mostrar en una anchura estándar de terminal de 80 columnas. El siguiente cuadro lista las opciones de línea de comando comunes que se utilizan para seleccionar qué aspectos de un proceso se listan.

Table 1. Opciones comunes del comando ps para la selección de salida

Opción Formato de la salida

-f listado "completo"

-l, l formato largo

-j, j formato de trabajos

-o, o, --formato str

formato definido del usuario utilizando campos especificados por str (campos disponibles para str se pueden listar con ps L o consultando la página de manual ps(1)).

Además, las siguientes opciones pueden utilizarse para modificar la forma de presentar la información.

Table 2. Opciones comunes del comando ps para dar formato a la salida

Opción Formato de la salida

-H Muestra la jerarquía del proceso

f, --forest Muestra la jerarquía de proceso incluyendo las representaciones ASCII

h No imprime las líneas del encabezado

-w salida "ancha" (incluye nombres de los comandos más largos)

Managing Processes

5

Rarezas del comando ps

El comando ps, posiblemente más que cualquier otro comando en Linux, tiene sus rarezas asociadas con sus opciones. En la práctica, los usuarios tienden a experimentar hasta encontrar combinaciones que les funcionen y luego se habitúan a ellas. Por ejemplo, el autor prefiere el comando ps aux para propósitos generales de todos los procesos, mientras que otros preferirían el comando ps -ef. El cuadro anterior ofrece una "ayuda de trabajo" bastante buena para el principiante.

Las opciones de línea de comandos tienden a clasificarse en dos categorías, aquellas con el tradicional guión inicial (opciones de estilo "Unix98") y otras sin (opciones de estilo "BSD"). A menudo, una funcionalidad determinada se representa por una de cada una de ellas. Al agrupar opciones de una sola letra, sólo pueden agruparse opciones del mismo estilo. Por ejemplo, ps axf es lo mismo que ps a x f, pero diferente de ps a x -f.

Control de procesos con el comando top

El comando ps muestra estadísticas para procesos especificados en el momento que se ejecuta el comando, proporcionando una instantánea de una instancia en tiempo. En contraste, el comando top sirve para controlar el estado general de los asuntos de procesos en la máquina.

Se espera que el comando top se ejecute desde dentro de una terminal. Éste remplazará la línea de comandos por una tabla de los actuales procesos en ejecución, el cual se actualiza a cada instante. A continuación se muestra la pantalla de un usuario después de ejecutar el comando top.

17:46:38 up 4:28, 7 users, load average: 0.07, 0.02, 0.00 101 processes: 100 sleeping, 1 running, 0 zombie, 0 stopped CPU states: 3.4% user 1.0% system 0.0% nice 0.0% iowait 95.4% idle Mem: 255232k av, 232796k used, 22436k free, 0k shrd, 32404k buff 146208k actv, 33884k in_d, 4716k in_c Swap: 522104k av, 88368k used, 433736k free 104280k cached PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND 1150 einstein 15 0 4468 4108 2252 S 2.9 1.6 0:51 0 metacity 1186 einstein 15 0 3132 2112 1436 S 0.9 0.8 0:04 0 battstat-appl 3057 einstein 15 0 19596 18M 12356 S 0.9 7.5 0:06 0 galeon-bin 3622 maxwell 22 0 1088 1088 856 R 0.9 0.4 0:00 0 top 1 root 15 0 108 76 52 S 0.0 0.0 0:04 0 init 2 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 keventd 3 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 kapmd

Managing Processes

6

4 root 34 19 0 0 0 SWN 0.0 0.0 0:00 0 ksoftirqd_CPU 9 root 25 0 0 0 0 SW 0.0 0.0 0:00 0 bdflush 5 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 kswapd 6 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 kscand/DMA 7 root 15 0 0 0 0 SW 0.0 0.0 0:06 0 kscand/Normal 8 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 kscand/HighMe 10 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 kupdated 11 root 25 0 0 0 0 SW 0.0 0.0 0:00 0 mdrecoveryd 15 root 15 0 0 0 0 SW 0.0 0.0 0:01 0 kjournald

Mientras el comando está ejecutándose, el teclado está "vivo". En otras palabras, el comando top responderá a pulsaciones sin esperar a la tecla enter. El siguiente cuadro lista algunas de las teclas más utilizadas.

Table 1. Comandos top más utilizados

Presionar tecla Comando

q quit

h o ? ayuda

s establecer el retraso entre las actualizaciones (en segundos)

space mostrar actualización

M Clasificar procesos por tamaño de memoria

P Clasificar procesos por actividad de la CPU (procesador)

u Reducir procesos visualizados pertenecientes a un usuario específico

k Matar un proceso (enviar una señal a un proceso)

r renice un proceso

Los últimos dos comandos, los cuales pueden matar o renice un proceso utilizan conceptos que cubriremos con más detalle en una próxima lección.

Aunque por lo general top funciona sin la configuración de línea de comandos es compatible con las siguientes opciones:

Table 2. Opciones para el comando top

Opción Efecto

-d Demora segundos segundos entre actualizaciones (por defecto = 5

Managing Processes

7

Opción Efecto segundos segundos).

-q Actualiza tan pronto como sea posible.

-n N Se ejecuta para iteraciones N, luego sale.

-b Se ejecuta en "modo por lote" simplemente como si escribiera a una terminal tonta.

Procesos de control con la aplicación gnome-system-monitor

Si se ejecuta un servidor X, el entorno de escritorio de GNOME proporciona una aplicación similar en función a top con los beneficios (y problemas) de una aplicación gráfica. La aplicación se puede iniciar desde una línea de comandos como gnome-system-monitor o desde el menú de aplicaciones predeterminado, seleccionando Herramientas: monitor del sistema.

Figure 1. Monitor del sistema GNOME

Al igual que el comando top, la aplicación Monitor del sistema presenta una lista de procesos ejecutándose en la máquina local, actualizando la lista cada pocos segundos. En su configuración por defecto, la aplicación Monitor del sistema provee una interfaz mucho más simple: lista sólo los procesos pertenecientes al usuario que inició la aplicación y reduce el número de columnas a la memoria del comando del proceso, el propietario, ID de proceso, las medidas simples de la memoria del proceso y la utilización de la CPU. Los procesos pueden clasificarse por cualquiera de estos campos con un sólo clic en el título de la columna.

En la esquina superior derecha de la ventana, un menú emergente permite al usuario escoger entre desplegar todos los procesos pertenecientes al usuario (por defecto) o sólo los procesos en el estado de "ejecución".

Cuando se hace click derecho en un proceso, un menú emergente permite al usuario realizar muchas de las acciones que top le permitió, tales como reniciar o matar un proceso a través de una interfaz más sencilla (y no tan flexible).

Figure 2. Haciendo click derecho en un proceso en el Monitor del sistema GNOME

El Monitor del Sistema puede configurarse abriendo el menú de selecciónEditor:Preferencias. Dentro del diálogo de Preferencias, el usuario puede establecer el intervalo de actualización (en segundos) y configurar muchos más campos para ser visualizados.

Figure 3. Campos de configuración en el monitor de sistema GNOME

Managing Processes

8

Por último, el Monitor de Sistema provee un segundo panel, el cual muestra gráficas de todo el uso de la CPU y de la memoria versus tiempo y un cuadro de uso del disco (esencialmente la salida del comando df).

Figure 4. Panel del monitor de sistema GNOME

Localización de procesos con el comando pgrep.

A menudo, los usuarios tratan de localizar información acerca de procesos identificados por el comando que están ejecutando o el usuario que está ejecutándolos. Una técnica es listar todos los procesos y utilizar el comando grep para reducir la información. A continuación, maxwell primero busca todas las instancias del demonio sshd y luego busca los procesos pertenecientes al usuario maxwell.

[maxwell@station maxwell]$ ps aux | grep sshd root 829 0.0 0.0 3436 4 ? S 0 9:13 0:00 /usr/sbin/sshd maxwell 2200 0.0 0.2 3572 640 pts/8 S 1 0:10 0:00 grep sshd [maxwell@station maxwell]$ ps aux | grep maxwell root 2109 0.0 0.3 4108 876 pts/8 S 1 0:05 0:00 su - maxwell maxwell 2112 0.0 0.4 4312 1268 pts/8 S 1 0:05 0:00 -bash maxwell 2146 1.4 8.3 89256 21232 pts/8 S 1 0:05 0:04 /usr/lib/mozilla- maxwell 2201 0.0 0.2 2676 724 pts/8 R 1 0:10 0:00 ps aux maxwell 2202 0.0 0.2 3576 644 pts/8 S 1 0:10 0:00 grep maxwell

Aunque maxwell puede encontrar la información que necesita hay algunos aspectos no muy agradables.

1. El método no es exacto. Observe que, en la segunda búsqueda, apareció un proceso su no porque le perteneciera a maxwell, sino porque la palabra maxwell era uno se sus argumentos.

2. Igualmente, el comando grep suele aparecerse en la salida. 3. El comando compuesto puede ser complicado de teclear.

El comando pgrep fue creado para tratar estos problemas. pgrep permite a los usuarios listar rápidamente procesos por nombre de comando, usuario, terminal o grupo.

pgrep [OPCIONES] [PATRÓN]

Su argumento opcional, si se suministra, se interpreta como un patrón de expresión regular extendido coincidente con nombres de comando. Las siguientes opciones también pueden utilizarse para clasificar la búsqueda.

Managing Processes

9

Table 1. Opciones comunes para especificar el criterio de selección del proceso pgrep.

Opción Efecto

-n Selecciona únicamente los procesos coincidentes iniciados más recientemente.

-u USER Selecciona procesos pertenecientes al usuario USER.

-t TERM Selecciona procesos controlados por terminal TERM.

Además, la siguiente opción puede utilizarse para modificar el formato de la salida del comando.

Table 2. Opciones comunes para especificar el formato de salida pgrep

Opción Efecto

-d delimitador

Usa delimitador para delimitar cada ID de proceso (por defecto se utiliza una nueva línea).

-l Lista el nombre del proceso y el ID del proceso.

Para una lista completa de opciones consulte la página de manual pgrep(1).

A manera de ejemplo, maxwell repetirá dos listados del proceso anterior mediante el comando pgrep. [1]

[maxwell@station maxwell]$ pgrep -l sshd 829 sshd [maxwell@station maxwell]$ pgrep -lu maxwell 2112 bash 2146 mozilla-bin 2155 mozilla-bin 2156 mozilla-bin 2157 mozilla-bin

Ejemplos

Ver todos los procesos con el formato de "usuario orientado"

En la siguiente transcripción, maxwell utiliza el comando ps -e u para listar todos los procesos (-e) con el formato de "usuario orientado" (u).

[maxwell@station maxwell]$ ps -e u USER PID %CPU %MEM VSZ RSS TTY STAT S TART TIME COMMAND root 1 0.0 0.0 1380 76 ? S O ct12 0:04 init [ root 2 0.0 0.0 0 0 ? SW O ct12 0:00 [keventd] root 3 0.0 0.0 0 0 ? SW O ct12 0:00 [kapmd] ...

Managing Processes

10

root 174 0.0 0.0 0 0 ? SW O ct12 0:00 [kjournald] root 250 0.0 0.0 1356 4 tty2 S O ct12 0:00 /sbin/mingetty tt root 496 0.0 0.1 2104 448 ? S O ct12 0:00 /sbin/dhclient -1 root 566 0.0 0.0 1448 160 ? S O ct12 0:00 syslogd -m 0 root 570 0.0 0.0 1376 164 ? S O ct12 0:00 klogd -x rpc 588 0.0 0.0 1548 104 ? S O ct12 0:00 portmap ... maxwell 4202 0.0 1.3 57948 3400 ? S O ct12 0:02 nautilus --no-def maxwell 4204 0.0 0.1 16392 436 ? S O ct12 0:00 magicdev --sm-cli maxwell 4207 0.0 0.5 16784 1500 ? S O ct12 0:00 eggcups --sm-clie maxwell 4210 0.0 0.3 11596 988 ? S O ct12 0:00 pam-panel-icon -- maxwell 4212 0.1 0.8 24464 2152 ? S O ct12 0:41 /usr/bin/python / root 4213 0.0 0.0 1416 136 ? S O ct12 0:00 /sbin/pam_timesta maxwell 4220 0.0 0.3 17024 1012 ? S O ct12 0:00 /usr/libexec/noti maxwell 4293 2.4 1.4 18356 3760 ? S O ct12 15:28 gnome-system-moni apache 5048 0.0 0.6 18424 1776 ? S O ct12 0:00 /usr/sbin/httpd ... maxwell 13166 0.7 0.5 4304 1392 pts/5 S 0 7:35 0:00 -bash maxwell 13200 0.0 0.2 2696 744 pts/5 R 0 7:35 0:00 ps -e u

El "usuario orientado"muestra el usuario que está ejecutando el proceso, el id de proceso y una estimación aproximada de la cantidad de CPU y memoria que el proceso está consumiendo como también el estado del proceso. (los estados de procesos se tratarán en una próxima lección).

Ver los procesos de un usuario con el formato "largo"

En la siguiente transcripción, maxwell utiliza el comando ps -U maxwell l para listar todos sus procesos (-U maxwell) con el formato "largo " (l).

[maxwell@station maxwell]$ ps -U maxwell l F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND 4 515 4132 1062 15 0 18632 4 schedu S ? 0:02 /usr/bin/gnom 1 515 4175 4132 15 0 3068 72 schedu S ? 0:00 /usr/bin/ssh- 0 515 4180 1 15 0 11384 776 schedu S ? 0:00 /usr/libexec/ 0 515 4182 1 15 0 6364 4 schedu S ? 0:00 /usr/libexec/

Managing Processes

11

0 515 4184 1 15 0 17336 4 schedu S ? 0:00 gnome-setting 0 515 4193 1 15 0 3728 620 schedu S ? 0:00 xscreensaver 0 515 4196 1 15 0 12816 1884 schedu S ? 0:08 /usr/bin/meta 0 515 4200 1 15 0 21160 3340 schedu S ? 0:05 gnome-panel - 0 515 4202 1 15 0 57948 3192 schedu S ? 0:02 nautilus --no 0 515 4204 1 15 0 16392 424 schedu S ? 0:00 magicdev --sm 0 515 4207 1 15 0 16784 1348 schedu S ? 0:00 eggcups --sm- 0 515 4210 1 15 0 11596 908 schedu S ? 0:00 pam-panel-ico 0 515 4212 1 15 0 24464 2152 schedu S ? 0:43 /usr/bin/pyth 0 0 4213 4210 15 0 1416 136 schedu S ? 0:00 /sbin/pam_tim 0 515 4220 1 15 0 17024 756 schedu S ? 0:00 /usr/libexec/ 0 515 4293 1 15 0 18356 3760 schedu S ? 15:43 gnome-system- 4 515 13166 13163 15 0 4304 1388 wait4 S pts/5 0:00 -bash 0 515 13201 4193 25 10 6676 2592 schedu SN ? 0:00 pulsar -root 0 515 13265 13166 20 0 3140 1188 - R pts/5 0:00 ps -U maxwell

El formato largo se enfoca en parámetros de programación, tales como la prioridad y el niceness del proceso, los cuales se tratarán más adelante.

Ver un comando determinado con el formato "trabajo orientado"

En la siguiente transcripción, maxwell utiliza el comando ps -C bash j para listar todas las instancias del comando bash (-C bash) con el formato de "trabajo orientado" (j ).

[maxwell@station maxwell]$ ps -C bash j PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 1184 2311 2311 2311 pts/4 2311 S 2291 0:01 bash 1184 2565 2565 2565 pts/0 2565 S 2291 0:04 bash 1184 2757 2757 2757 pts/2 2757 S 2291 0:00 bash 1184 3024 3024 3024 pts/3 3052 S 2291 0:00 bash 1184 3348 3348 3348 pts/6 3348 S 2291 0:00 bash 1184 6033 6033 6033 pts/5 13414 S 2291 0:00 bash 1184 6534 6534 6534 pts/8 6534 S 2291 0:00 bash 13163 13166 13166 6033 pts/5 13414 S 515 0:00 -bash

El formato de trabajo orientado se enfoca en los procesos padre, grupos de proceso, grupos de sesión y terminales de control. Muchos de estos conceptos se discutirán más tarde en otros cuadernos.

Managing Processes

12

Intrigado porque el proceso padre de muchas de estas shells parece ser el proceso ID 1184, maxwell continúa examinando ese proceso individual.

[maxwell@station maxwell]$ ps u 1184 USER PID %CPU %MEM VSZ RSS TTY STAT S TART TIME COMMAND einstein 1184 0.2 3.3 26900 8660 ? S O ct12 2:51 /usr/bin/gnome-te

Aparentemente, todas las shells bash se iniciaron desde dentro de una gnome-terminal.

Ver procesos con el formato personalizado

Intrigado por ver los aspectos que un proceso puede visualizar con el comando ps, maxwell utiliza ps L para listar los posibles encabezados.

[maxwell@station maxwell]$ ps L %cpu %CPU %mem %MEM alarm ALARM args COMMAND blocked BLOCKED bsdstart START bsdtime TIME c C ... vsize VSZ vsz VSZ wchan WCHAN

Intrigado por el campo alarm, maxwell desea ver los procesos que tienen alarmas pendientes. Utiliza la opción -o para listar todas las alarmas pendientes y comandos.

[maxwell@station maxwell]$ ps -e -o alarm,cmd ALARM CMD - init [ - [keventd] - [kapmd] ... 30.00 syslogd -m 0 ...

Observando que todas las entradas "interesantes" comienzan con números, maxwell utiliza el comando grep para reducir su salida a líneas que comienzan con cualquier número o espacio pero cuyo primer caracter de no espacio sea un dígito.

[maxwell@station maxwell]$ ps -e -o alarm,cmd | grep "^ *[0-9]" 30.00 syslogd -m 0 15.00 /usr/sbin/automount --timeout 60 /misc file / etc/auto.misc 3600 /usr/sbin/sshd 3600 sendmail: accepting connections 3600 sendmail: Queue runner@01:00:00 for /var/spoo l/clientmqueue 300 /usr/bin/gdm-binary -nodaemon 10.00 /usr/bin/ssh-agent /etc/X11/xinit/Xclients

Managing Processes

13

10.00 /usr/bin/ssh-agent /etc/X11/xinit/Xclients

Estas son las utilidades que piden ser notificadas cada 15 minutos, cada hora, etc., presumiblemente para sondear alguna actividad.

Ejercicios en línea

Lab Exercise Objetivo: Ver la información sobre los procesos

Tiempo estimado: 20 minutos.

Especificaciones

Con el fin de tener un conjunto fijo de procesos para examinar, usted debe tomar una instantánea de todos los procesos actuales en su máquina. Utilice la siguiente secuencia de comandos para capturar primero los encabezados de las columnas del comando ps aux dentro de un archivo llamado snapshot . Luego vuelva a ejecutar el comando ps aux, eliminando el encabezado y clasificando el resto de la salida de acuerdo al tamaño de la memoria virtual de cada proceso. La lista clasificada de procesos se agregará luego al encabezado previamente capturado en el archivo snapshot .

Es más fácil de lo que parece.

[student@station student]$ ps aux | head -1 > snapshot [student@station student]$ ps aux | tail +2 | sort -rn -k4 >> snapshot [student@station student]$ head -5 snapshot USER PID %CPU %MEM VSZ RSS TTY STAT S TART TIME COMMAND einstein 3057 0.2 7.4 97088 18932 ? S O ct12 2:01 /usr/bin/galeon- root 1063 14.3 6.2 36528 15936 ? S O ct12 163:48 /usr/X11R6/bin/X einstein 1184 0.2 3.8 27160 9868 ? S O ct12 3:00 /usr/bin/gnome-t einstein 1164 0.0 3.0 27856 7792 ? S O ct12 0:11 /usr/bin/python

Utilice su archivo de snapshot para contestar las siguientes preguntas.

1. En el archivo ~/biggest.pid almacene el ID de proceso del proceso con el mayor tamaño de memoria virtual (la columna VSZ).

2. Experimente con el comando cut, hasta que pueda extraer la letra inicial de la columna del campo STAT. Esta estará llena casi exclusivamente de letras “R” y “S”, lo que implica que está en estado de ejecución o dormido. Grabe esta columna extraída (a excepción del encabezado) dentro de un archivo llamado ~/pstates.txt .

3. Utilice el comando grep, quizás con el comando wc para determinar el número de instancias en ejecución del programa /sbin/mingetty . Almacene la pregunta como un sólo número en el archivo ~/nmingetty.txt .

Managing Processes

14

4. Utilice el comando grep, quizás con el comando wc, para determinar la cantidad de procesos en ejecución como usuario root. Almacene la respuesta como un sólo número en el archivo ~/nroot.txt .

5. Inicie el comando top en una terminal y déjelo ejecutando mientras califica su ejercicio.

No modifique ni suprima su archivo snapshot hasta no haber terminado de calificar su ejercicio.

Deliverables

Question 1

1. El archivo ~/biggest.pid que contiene el ID de proceso del proceso con la

memoria virtual más grande. 2. El archivo ~/pstates.txt que contiene la columna extraída de los estados de

proceso, a excepción de la línea de encabezado. 3. El archivo ~/nmingetty.txt que contiene el número de instancias del

programa /sbin/mingetty ejecutándose en su máquina. 4. El archivo ~/nroot.txt que contiene el número de procesos ejecutándose como

el usuario root de la máquina. 5. Una instancia en ejecución del comando top.

Capítulo 2 Estados del proceso

Conceptos clave

• En Linux, el primer proceso, /sbin/init , lo inicia el kernel en el arranque. Todos los demás procesos son el resultado de un proceso padre que se duplica o bifurca.

• Un proceso comienza a ejecutar un nuevo comando a través de un proceso llamado execing.

• Los nuevos comandos suelen ejecutarse mediante un proceso (a menudo una shell) primero mediante una bifurcación y luego ejecutando un nuevo comando. Este mecanismo se conoce como el mecanismo fork y exec.

• Los procesos siempre pueden encontrarse en uno de los cinco estados: ejecutable, dormido voluntario, dormido involuntario, detenido o zombi.

• La ascendencia del proceso puede verse con el comando pstree. • Cuando un proceso muere, el padre del proceso debe recolectar su información

del código de retorno y del uso de recursos. • Cuando un padre muere antes que sus hijos, el primer proceso hereda los

huérfanos (usualmente /sbin/init ).

Managing Processes

15

Ciclo de vida de un proceso

Cómo se inician los procesos

En Linux (y Unix), a diferencia de muchos otros sistemas operativos, la creación de proceso y la ejecución de comandos son conceptos separados. Aunque un nuevo proceso es creado para que pueda ejecutarse en un comando especificado (tal como la shell bash creando un proceso para ejecutar el comando chmod), los procesos pueden crearse sin ejecutar un nuevo comando y los nuevos comandos pueden ejecutarse sin crear un nuevo proceso.

Creación de un nuevo proceso (forking)

Los nuevos procesos se crean mediante una técnica llamada forking. Cuando un proceso se bifurca, crea un duplicado de sí mismo. Inmediatamente después de una bifurcación, el proceso recién creado (el hijo) es un duplicado exacto del proceso original (el padre). El hijo hereda una copia idéntica de la memoria del proceso original, los archivos abiertos de padre, copias idénticas de los parámetros del padre, tales como el directorio de trabajo actual o umask. La única diferencia entre el padre y el hijo es la información heredada del hijo (el hijo tiene un ID de proceso diferente y un proceso de padre diferente, para los principiantes), y (para los programadores en la audiencia) el valor de retorno de la llamada al sistema fork() .

Como un aparte rápido para los programadores en la audiencia, un fork suele implementarse mediante una estructura similar a la siguiente:

int rc, child_pid; rc = fork(); if (rc == -1) { perror("bad fork"); } else if (rc == 0) { do_child(); } else { child_pid = rc; do_parent(child_pid); }

Cuando un proceso desea crear un nuevo proceso, acude al sistema de llamado fork() (sin argumentos). Aunque sólo un proceso entra en el llamado fork() , dos procesos retornan. Para el proceso recién creado (el hijo), el valor de retorno es 0. Para el proceso original (el padre), el valor de retorno es el ID del proceso de hijo. Al bifurcar este valor, el hijo puede ahora salir a hacer cualquier cosa que hubiera empezado a hacer (que suele involucrar exec(), ver lo siguiente) y el padre puede continuar haciendo sus cosas.

Ejecución de un nuevo comando (Execing)

Managing Processes

16

Los nuevos comandos se ejecutan a través de un técnica llamada execing (acortamiento en inglés para executing). Cuando se ejecuta un nuevo comando, el proceso actual borra y libera la mayoría de sus recursos y carga una nueva colección de instrucciones desde el comando especificado en el sistema de archivos. La ejecución inicia con el punto de entrada del nuevo programa.

Después de utilizar ejecutar un nuevo comando, el nuevo comando todavía es el mismo proceso. Tiene el mismo ID de proceso y muchos de los mismos parámetros (tales como su utilización de recursos, la umask y el directorio actual de trabajo). Apenas olvida su comando anterior y adopta uno nuevo.

De nuevo para algunos programadores, la ejecución de un nuevo comando se realiza mediante una o varias variantes de la llamada al sistema execve() tal como la llamada de la biblioteca execl().

rc = execl("chmod", "chmod 755 /etc/passwd"); perror("bad exec");

El proceso escribe la llamada execl(...), especificando el nuevo comando que se va a ejecutar. Si todo sale bien, la llamada execl(...) nunca retorna. En su lugar, la ejecución se realiza en el punto de entrada (por ejemplo, main()) del nuevo programa. Si por la misma razón execl(...) retorna, debe ser un error (tal como no poder localizar el ejecutable del comando en el sistema de archivos).

Combinación de dos: Fork y Exec

Algunos de los programas pueden utilizar fork sin ejecutar un nuevo comando. Ejemplos incluyen demonios de red, que bifurcan un nuevo hijo para manejar una conexión de un cliente específico, mientras el padre retorna para escuchar nuevos clientes. Otros programas podrían utilizar exec sin bifurcación. Ejemplos incluyen al comando login, el cual se convierte en la shell de inicio de sesión del usuario después de confirmar la contraseña del usuario. Sin embargo, para las shells en particular, fork y exec suelen ir de la mano. Cuando se ejecuta un comando, la shell bash primero bifurca una nueva shell bash. Luego, el hijo ejecuta el nuevo comando apropiado, mientras que el padre espera que el hijo muera para generar un nuevo intérprete de comandos.

El linaje de los procesos (y el comando pstree)

Tras el arranque del sistema, una de las responsabilidades del sistema del Kernel de Linux es iniciar el proceso por primera vez (usualmente/sbin/init ). Todos los otros procesos son iniciados porque se bifurcó un proceso ya existente.[1]

Debido a que cada proceso a excepción del primero se crea por bifurcación, dentro de los procesos existe un linaje bien definido de relaciones padre e hijo. El primer proceso iniciado por el kernel inicia fuera del árbol de familia, el cual puede examinarse con el comando pstree.

Managing Processes

17

[maxwell@station maxwell]$ pstree init-+-apmd |-atd |-automount |-battstat-applet ... |-evolution-execu |-evolution-mail |-fetchmail |-galeon-bin |-gconfd-1 |-2*[gconfd-2] |-gdm-binary-+-gdm-binary-+-X | | `-gnome-session---ss h-agent | `-gdm-binary---gnome-session---ss h-agent |-2*[gnome-panel] |-2*[gnome-settings-] |-gnome-system-mo |-gnome-terminal-+-3*[bash] | |-bash---man---sh---sh---less | |-bash---mutt | |-bash---su---bash---pstree | `-gnome-pty-helpe |-gpm |-gvim |-httpd---11*[httpd] |-kapmd |-keventd |-khubd ...

Cómo muere un proceso

Cuando un proceso muere ya sea que muera normalmente seleccionando exit o anormalmente como el resultado de recibir una señal. Aquí tratamos la salida normal del proceso, dejando para más adelante la discusión acerca sobre la señales.

Hemos mencionado anteriormente que los procesos dejan atrás un código de estatus cuando mueren (también llamado valor de retorno) en la forma de un número entero, (recuerde la shell bash que utiliza la variable $? para almacenar el valor de retorno del comando ejecutado previamente). Cuando un proceso sale, todos sus recursos se liberan, a excepción del código de retorno (y alguna información de utilización de recursos contables). Es responsabilidad del padre del proceso coleccionar esta información y liberar los últimos recursos del hijo muerto. Por ejemplo, cuando la shell se bifurca y exec el comando chmod, es responsabilidad de la shell bash padre recoger el valor de retorno del comando cerrado chmod.

Huérfanos

Si es responsabilidad de los padres limpiar después de sus hijos, ¿qué sucede si el padre muere antes que el hijo? El hijo queda huérfano. Una de las responsabilidades especiales del primer proceso iniciado por el kernel es "adoptar" huérfanos, (observe que en la salida del comando pstree, el primer proceso tiene un número

Managing Processes

18

desproporcionado de hijos. La mayoría de estos fueron adoptados como huérfanos de otros procesos).

Zombis

Entre el momento en que un proceso sale, liberando la mayoría de sus recursos, y el momento en que su padre recoge su valor de retorno, liberando el resto de sus recursos, el proceso hijo se encuentra en un estado especial conocido como Zombi. Cada proceso pasa a través de un estado transitorio zombi. Los usuarios tienen que estar mirando justo en el momento preciso (con el comando ps, por ejemplo) para ver un zombi. Ellos se aparecen en la lista de procesos, pero no ocupan memoria, ni tiempo de CPU, ni ningún otro sistema de recursos. Ellos son sólo la sombra de un proceso anterior esperando que su padre llegue y los termine.

Padres negligentes y zombis de larga vida

Ocasionalmente, los procesos padres pueden ser descuidados. Comienzan procesos hijos pero nunca regresan a limpiar lo que dejan. Cuando esto ocurre (usualmente debido a un error de programador), el hijo puede salir, entrar en estado zombi y quedarse ahí. Esto suele suceder cuando los usuarios son testigos de procesos zombis mediante el comando ps, por ejemplo.

Deshacerse de zombis es quizás el concepto básico más incomprendido de Linux (y Unix). Mucha gente dirá que no hay forma de deshacerse de ellos, excepto volviendo a arrancar la máquina. ¿Sabe cómo deshacerse de zombis de larga vida utilizando las claves tratadas en esta sección?

Los 5 estados del proceso

La sección anterior trató la manera como se inician y mueren los procesos. Mientras los procesos están vivos, siempre están en uno de los cinco estados del proceso, los cuales efectúan el cómo y cuándo tienen acceso a la CPU. El siguiente listado muestra los cinco estados, junto con la letra convencional utilizada por ps, top y otros comandos para identificar el estado actual de un proceso.

Ejecutable (R)

Los procesos en un estado ejecutable son procesos que si tienen la oportunidad de acceder la CPU, la aprovecharían. Los procesos múltiples suelen estar en un estado de ejecución, pero como sólo puede ejecutarse un proceso en la CPU en determinado tiempo, sólo uno de estos procesos en realidad estará ejecutándose en un momento dado. Puesto que los procesos de ejecución entran y salen de la CPU tan rápidamente en el sistema de Linux, parece como si todos los procesos se estuvieran ejecutando de manera simultánea. [1]

Dormido voluntario (interrumpible) (S)

Managing Processes

19

Como el nombre lo implica, un proceso que está dormido voluntario ha elegido estar así. Por lo general, este es un proceso que no tiene nada que hacer hasta que suceda algo interesante. Un ejemplo clásico es el demonio de red httpd , el cual es un proceso que implementa un servidor de red. En medio de solicitudes de un cliente (navegador de red), el servidor no tiene nada que hacer, y elige irse a dormir. Otro ejemplo sería el comando top, que lista procesos cada cinco segundos. Mientras espera que pasen los cinco segundos, se duerme voluntariamente. Cuando el proceso esté interesado en que algo suceda (tal como cuando el cliente de red hace una solicitud o los cinco segundos expiran), el proceso dormido vuelve al estado ejecutable.

Dormido involuntario (no interrumpible) (D)

En ocasiones, dos procesos tratan de acceder el mismo recurso de sistema al mismo tiempo. Por ejemplo, un proceso trata de leer de un bloque o un disco mientras que el bloque está siendo escrito debido a otro proceso. En estas situaciones, el kernel fuerza al proceso a dormir. El proceso no eligió dormir, éste hubiera preferido ser ejecutable para poder hacer las cosas. Cuando el recurso es liberado, el kernel pondrá el proceso de nuevo en su estado ejecutable.

Aunque los procesos están constantemente durmiendo involuntariamente, no suelen estarlo por mucho tiempo. Como resultado, los usuarios no suelen ver los procesos en dormido involuntario, excepto en sistemas ocupados.

Procesos detenidos (suspendidos) (T)

Ocasionalmente, los usuarios deciden suspender procesos. Los procesos suspendidos no realizarán ninguna acción hasta no ser reiniciados por el usuario. En la shell bash, la secuencia de teclas CONTROL -Z puede utilizarse para suspender un proceso. En programación, los depuradores suelen suspender los programas que están depurándose cuando ciertos eventos suceden (como cuando se producen puntos de interrupción).

Procesos zombi (Z)

Como lo mencionamos antes, cada proceso muriendo pasa a través de un estado zombi transitorio. No obstante, en ocasiones, algunos se quedan en ese estado. Los procesos zombis han terminado de ejecutar, han liberado toda su memoria y casi todos sus recursos. Dado que no están consumiendo recursos, son poco más que una molestia que puede aparecer en listados de procesos.

Ver estados de procesos

Cuando se ve la salida de comandos tales como ps y top, los estados de procesos suelen enumerase bajo el encabezado STAT. El proceso es identificado por una de las siguientes letras:

Managing Processes

20

• Ejecutable - R • Dormido - S • Detenido - T • Dormido ininterrumpible - D • Zombi – Z

Ejemplos

Identificación de estados de procesos

[maxwell@station maxwell]$ ps -alx F UID PID PPID PRI NI VSZ RSS WCHAN STA T TTY TIME COMMAND 100 0 1 0 15 0 1344 436 schedu S ? 0:06 init 100 500 4248 775 15 0 4136 1412 wait4 S tty3 0:00 -bash 100 500 4292 776 15 0 4144 1420 schedu S tty4 0:00 -bash 004 0 1829 1774 17 0 1472 528 down D pts/3 0:00 updatedb 004 0 1827 1774 16 0 1464 520 - R pts/3 0:00 updatedb 000 500 4333 4292 15 0 7612 2616 do_sig T tty4 0:00 vim proj1_s 000 500 4334 4248 15 0 3612 1052 schedu S tty3 2:57 top 004 501 5486 1220 16 0 0 0 do_exi Z ? 0:00 [netstat 000 501 5793 2600 15 0 7708 2816 wait4 S pts/0 0:00 vim c 000 501 5798 5793 16 0 3804 944 wait4 S pts/0 0:00 /bin/bash - 040 501 5799 5798 17 0 3808 1000 wait4 S pts/0 0:00 /bin/bash - 000 501 5800 5799 17 0 3148 1240 - R pts/0 0:00 ps -alx 000 501 5801 5799 17 0 3144 420 pipe_w S pts/0 0:00 tail

Un proceso dormido (voluntario). El proceso init está esperando que algo "interesante" suceda tal como un huérfano recién creado a heredar.

Un proceso dormido(involuntario) o "bloqueado". El comando updatedb está compitiendo por algún recurso en el sistema probablemente con la otra instancia del proceso updatedb justo debajo de éste.

Un proceso detenido. Este editor vim probablemente ha sido suspendido manualmente con la secuencia de teclas CONTROL -Z.

Un proceso zombi probablemente abandonado por un navegador de red galeon negligente.

Un proceso ejecutable en este caso el comando ejecutable ps.

Managing Processes

21

Ejercicios en línea

Lab Exercise Objetivo: Explorar diferentes estados de procesos

Estimated Time: 10 mins.

Especificaciones

1. Con el fin de explorar los estados de procesos debemos crear procesos que estén compitiendo por los mismos recursos. Utilice un editor de texto sencillo para crear el siguiente guión, almacénelo como ~/clobber_it.sh y hágalo ejecutable.

2. [maxwell@station maxwell]$ cat clobber_it.sh 3. #!/bin/bash 4. 5. for i in $(seq 1000); do 6. echo "hello world" > poor_overworked_file 7. done

8. Aunque este guión escribirá al pobre archivo sobrecargado 1000 veces, lo hará de forma secuencial y así nunca estará compitiendo por acceder al archivo. Dado que necesitamos procesos múltiples compitiendo por el mismo recurso, cree también el mismo script. Nómbrelo ~/clobber_it_lots.sh y hágalo ejecutable.

9. [maxwell@station maxwell]$ cat clobber_it_lots.sh 10. #!/bin/bash 11. 12. for i in $(seq 1000); do 13. ./clobber_it.sh & 14. done

Esto debería funcionar.

15. In one terminal, run the command top -d1. This should run the top command, updating continuously. While top is running, use the U command to limit the display to your own processes (i.e., type in your own username).

16. When we say go, in a separate terminal (either another terminal window in an X graphical environment, or a separate virtual console), run the script clobber_it_lots.sh . This will start about 1000 processes on your machine, which will obviously stress the system, but it should be able to handle it. [1] The system may seem sluggish, but with patience, it should still be responsive. If things get unbearable, the script can be canceled with a CTRL -C. We haven't said go yet.

17. Mientras el guión esté ejecutándose, observe la terminal con el comando top. Usted debería ver muchos procesos iniciándose y deteniéndose como también muchos procesos en el estado “D”. Si tiene suerte, podría capturar incluso un zombi. Aún no hemos dicho que empiece.

18. También mientras se esté ejecutando el script, en otro terminal, ejecute el comando ps aux y redirija la salida al archivo ~/lotsa_processes.txt .

Managing Processes

22

Observe el contenido del script y asegúrese que al menos cinco procesos en el estado “D” hayan sido registrados. Aún no hemos dicho que empiece.

19. ¡Empiece! 20. Después de crear su archivo ~/lotsa_processes.txt y de sentir que ha

entendido, puede cancelar el script clobber_it_lots.sh con la secuencia CONTROL -C y abandone el comando top.

Deliverables

Question 1

1. El archivo ~/lotsa_processes.txt que contiene la salida del comando ps aux

con al menos 5 instancias del proceso en el estado “D” (ininterrumpible).

Capítulo 3 Programación de procesos: nice y renice

Conceptos clave

• Una tarea primaria del kernel de Linux es la programación de procesos. • Cada proceso tiene un valor de niceness que influye en su programación. • Los comandos nice y renice pueden cambiar la prioridad de programación de un

proceso.

Nomenclatura de programación de procesos

Una de las tareas fundamentales del kernel de Linux es asegurar que los procesos compartan recursos del sistema de manera efectiva. Uno de los recursos más importantes que tiene que compartirse es la CPU. La forma en que el kernel decide qué proceso tiene que ejecutarse en la CPU y la hora se conoce como programación.

Cada proceso tiene dos valores que influyen en su programación. El primero es un valor dinámico que el kernel cambia constantemente. El segundo, es un valor fijo que sólo de vez en cuando el usuario lo cambia. En la comunidad de código abierto, la nomenclatura utilizada para describir estos dos valores ha sido inconsistente lo que lleva a la confusión. En lo posible, este texto tratará de ser consistente con los comandos ps y top y se referirá al primer valor (dinámico) como la prioridad del proceso y al segundo valor (fijo) como el niceness del proceso.

Programación de procesos en esencia

Recientemente, se ha prestado mucha atención a los métodos utilizados por el kernel de Linux para implementar programación y la técnica ha variado con cada lanzamiento del kernel. Aunque la siguiente discusión no es correcta en detalle comunica en esencia la forma como el kernel de Linux programa procesos.

Managing Processes

23

Para ilustrar la programación de un modo más fácil, maxwell iniciará cuatro versiones del comando cat, ejecutándose en el segundo plano, (los procesos se pueden ejecutar en segundo plano agregando el signo “&”), como se discutirá en una lección más adelante. Los comandos cat leen desde /dev/zero (un seudo dispositivo que actúa como una fuente infinita de ceros binarios) y escriben en /dev/null (un seudo dispositivo que bota todo lo que se escribe en él).

[maxwell@station maxwell]$ cat /dev/zero > /dev/null & [1] 6698 [maxwell@station maxwell]$ cat /dev/zero > /dev/null & [2] 6699 [maxwell@station maxwell]$ cat /dev/zero > /dev/null & [3] 6700 [maxwell@station maxwell]$ cat /dev/zero > /dev/null & [4] 6701

¿Por cuánto tiempo se ejecutarán estos comandos cat? Para siempre. El usuario maxwell controla los procesos en su máquina mediante el comando top.

00:25:43 up 11:07, 10 users, load average: 6.02, 5.08, 3.01 128 processes: 121 sleeping, 7 running, 0 zombie, 0 stopped CPU states: 8.5% user 3.2% system 4.6% nice 0.0% iowait 83.5% idle Mem: 255232k av, 251560k used, 3672k free, 0k shrd, 36592k buff 162724k actv, 33644k in_d, 3952k in_c Swap: 522104k av, 145148k used, 376956k free 74780k cached PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND 6698 maxwell 25 0 404 400 352 R 19.3 0.1 0:24 0 cat 6699 maxwell 22 0 400 400 352 R 19.3 0.1 0:24 0 cat 6700 maxwell 24 0 400 372 352 R 19.3 0.1 0:24 0 cat 6757 einstein 21 0 25992 24M 3596 R 17.4 9.7 0:04 0 jade 6701 maxwell 25 0 400 400 352 R 16.4 0.1 0:24 0 cat 6686 maxwell 35 10 6608 4836 1108 R N 4.8 1.8 0:44 0 xlyap 6758 maxwell 19 0 1120 1120 852 R 2.9 0.4 0:00 0 top 1063 root 15 0 33304 16M 692 S 1.9 6.5 33:56 0 X 1 root 15 0 108 76 52 S 0.0 0.0 0:04 0 init 2 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 keventd ...

Mientras observa el comando top, maxwell observa que los valores en la tercera columna (con la etiqueta PRI) están en constante cambio. Estos son los valores de "prioridad" dinámicos del proceso mencionados anteriormente. La cuarta columna (con la etiqueta NI) es el valor fijo de "niceness" del proceso.

Prioridades del proceso

Managing Processes

24

Cuando se programan los procesos, el kernel da a cada proceso un puñado de contadores. Cada vez que un proceso se programa en la CPU, entrega uno de sus contadores. Cuando decide qué proceso programar en la próxima CPU, el kernel escoge un proceso ejecutable con la mayoría de contadores. Eventualmente, el kernel alcanzará un estado donde todos los procesos ejecutables han utilizado sus contadores. Esto se conoce como el final de una programación epoch y en este punto el kernel inicia todos los procesos otra vez con un puñado de contadores.

Observe que los procesos que no están en estado ejecutable nunca entregan sus contadores. Sin embargo, si un proceso dormido se despertara de repente (porque algo interesante ha sucedido) y fuera enviado al estado ejecutable, muy probablemente tendría más contadores que procesos ejecutándose por un tiempo y le gustaría que fueran programados rápidamente en la CPU.

¿Cómo se relaciona esto con los valores demostrados en la columna PRI? Piense en esta columna como si fuera un número de procesos de contadores, restados de 40. Por lo tanto, los procesos con una prioridad inferior (como es listado por el comando top) tienen una ventaja en la programación. En la salida de arriba, los comandos cat, en constante ejecución, están consumiendo sus contadores. Sin embargo, el proceso init que está durmiendo en el segundo plano, no lo está.

Proceso niceness

Como se mencionó anteriormente, cada proceso también tiene un valor estático conocido como su valor de niceness. Este valor tiene un rango que va de -20 a 19 para cualquier proceso, iniciando en 0 por defecto. ¿Cómo influye un niceness de un proceso en su programación? Al comienzo de la programación puede pensar que el kernel resta un valor de niceness del proceso del número de contadores del proceso que se le ha asignado. Como resultado de procesos más, "amables" (aquellos con un alto valor de niceness) obtienen menos contadores y por lo tanto menos tiempo en la CPU, mientras que procesos más "ambiciosos" (aquellos con un valor de niceness menor que 0) obtienen más contadores y más tiempo en la CPU. Si un proceso "amable" es el único ejecutándose en la máquina entonces obtendría acceso total a la CPU.

Cambio del valor niceness de un proceso

Suponga que maxwell fuera a ejecutar una simulación física que le tomaría varios días completar. Al incrementar el valor de niceness del proceso, el proceso pacientemente esperaría si alguien más estuviera ejecutando procesos en la máquina. Si nadie más estuviera en la máquina, la simulación física tendría acceso total a la CPU.

Hay varias técnicas por las cuales maxwell podría alterar su valor de niceness del proceso.

Uso del comando nice para iniciar un comando con prioridad baja

Managing Processes

25

El comando nice se utiliza para establecer un valor de niceness del proceso al iniciar el proceso. Cuando maxwell inicia su simulación (la cual es un ejecutable en su directorio de inicio llamado ~/simulation ) lo hace lo más nice posible, con el valor de +19, (también coloca el proceso en segundo plano. No se preocupe por esto en este momento puesto que lo abarcaremos en una próxima lección).

[maxwell@station maxwell]$ nice -19 ./simulation &

Observe que la sintaxis puede confundir. El símbolo -19 no debería considerarse negativo 19 sino en cambio la opción numérica 19. El usuario maxwell de nuevo controla los procesos mediante el comando top. Los primeros pocos procesos listados se enumeran a continuación.

PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND 7192 maxwell 25 0 400 400 352 R 22.7 0.1 0:35 0 cat 7193 maxwell 25 0 400 400 352 R 22.7 0.1 0:35 0 cat 7191 maxwell 25 0 400 400 352 R 21.9 0.1 0:36 0 cat 7194 maxwell 25 0 404 404 352 R 21.9 0.1 0:35 0 cat 1184 einstein 15 0 11140 8708 3144 R 4.7 3.4 1:28 0 gnome-termina 7198 maxwell 39 19 404 404 352 R N 2.1 0.1 0:02 0 simulation 4293 maxwell 15 0 5164 5016 2384 S 1.7 1.9 6:07 0 gnome-system-

Como algo conveniente, el comando ps representa el estado de proceso con una “N” para indicar que el proceso ha aumentado su valor de niceness.

Dado que otros comandos cat están utilizando la máquina, la simulación de maxwell sólo está usando cerca del 2.1 % de la CPU.

Luego, maxwell se deshace de los comandos cat (mediante las técnicas que veremos en la siguiente lección).

[maxwell@station maxwell]$ killall cat [maxwell@station maxwell]$ [3] Terminated cat /dev/zero >/dev/n ull [4] Terminated cat /dev/zero >/dev/n ull [5] Terminated cat /dev/zero >/dev/n ull [6] Terminated cat /dev/zero >/dev/n ull

Cuando observa el comando top una vez más, su simulación, ahora el (casi) único proceso en la máquina, está recibiendo todo el tiempo de la CPU.

PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND 7198 maxwell 39 19 404 404 352 R N 94.4 0.1 0:51 0 simulation 7210 maxwell 20 0 1120 1120 852 R 2.8 0.4 0:00 0 top 1063 root 15 0 33516 17M 832 S 1.9 7.0 47:01 0 X 4212 maxwell 15 0 5828 3012 1072 S 0.9 1.1 0:21 0 rhn-applet-gu 1 root 15 0 108 76 52 S 0.0 0.0 0:04 0 init

Managing Processes

26

Como una sutileza adicional, el número especificado es el número que va a agregarse al valor de niceness de la shell actual. Esto rara vez se nota, dado que la mayoría de las shells se ejecutan con un niceness de 0. No obstante, si una shell estuviera ejecutándose con un valor de niceness de 10, la siguiente opción de línea de comando resultaría en la simulación que está ejecutándose con un valor de niceness de 15.

[maxwell@station maxwell]$ nice -5 ./simulation &

Uso de renice para alterar un proceso en ejecución

El comando renice puede utilizarse para cambiar el niceness de un proceso en ejecución. Los procesos pueden ser especificados por el ID del proceso, nombre de usuario, o nombre de grupo, dependiendo de cuál de las siguientes opciones se utilicen.

Table 1. Opciones para el comando renice

Opción Efecto

-p interpreta los argumentos restantes como ID del proceso (por defecto)

-u interpreta los argumentos restantes como nombres de usuarios.

-g interpreta los argumentos restantes como ID de grupo.

Suponga que maxwell ya ha iniciado su simulación sin alterar su valor de niceness.

[maxwell@station maxwell]$ ps -C simulation u USER PID %CPU %MEM VSZ RSS TTY STAT S TART TIME COMMAND maxwell 7348 58.9 0.1 3408 400 pts/5 R 01:29 0:50 simulation [maxwell@station maxwell]$ ps -C simulation l F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND 0 515 7348 6064 25 0 3408 400 - R pts/5 0:51 simulation

El proceso está recibiendo una gran cantidad de tiempo de la CPU.

El proceso tiene por defecto un valor de niceness de 0.

Decide ser más cortés con otras personas que podrían estar utilizando la máquina y utiliza el comando renice para elevar el valor de niceness del proceso. En la ausencia de cualquier opción, el comando renice espera un valor de niceness y un ID de proceso como sus dos argumentos.

[maxwell@station maxwell]$ renice 19 7347 7348: old priority 0, new priority 19

Observe la inconsistencia en la sintaxis. El comando renice a diferencia del comando nice, no espera que el valor de niceness sea especificado como una opción, sino como un argumento. De hecho, renice -19 7347 sería interpretado como un valor de niceness de -19. Enlodando más las aguas, la salida del comando renice se refiere al

Managing Processes

27

valor como una prioridad en lugar de un niceness, (como también lo hace alguna de la documentación relacionada).

Uso del comando top para otorgar otro valor de nice a un proceso

Como se mencionó antes, el comando top utiliza la tecla r para cambiar el valor nice de un proceso. Mientras controla procesos con top, al presionar r abrirá el siguiente diálogo que aparece encima de la lista de procesos.

PID to renice: 7347 Renice PID 7347 to value: 19

Hacer procesos mucho más ambiciosos

¿Qué sucedería si maxwell fuera malintencionado y quisiera hacer su simulación mucho más ambiciosa en lugar de más amable? Afortunadamente, para otros usuarios en la máquina, los usuarios normales no pueden bajar el niceness de un proceso. Esto trae dos implicaciones.

1. Debido a que los procesos inician con un niceness de 0 por defecto, los usuarios normales no pueden hacer procesos "ambiciosos" con valores de niceness negativos.

2. Una vez un proceso ha sido hecho nice, los usuarios normales no pueden volverlo "normal" otra vez .

Suponga que el administrador observó que la simulación de maxwell estaba tomando mucho tiempo de la CPU. Ella pudo utilizar el comando renice como root para elevar el niceness de maxwell y maxwell no pudo restaurarlo.

Ejemplos

Ver prioridades

Abajo hay varias tomas de pantalla ps -alx a medida que se ejecuta el proceso. Observe los campos "PRI" y "nice" a lo largo del tiempo. Son los campos 5 y 6 de izquierda a derecha.

[maxwell@station maxwell]$ find / 2>/dev/null >/dev/null & [1] 2739 [maxwell@station maxwell]$ ps -alx F UID PID PPID PRI NI VSZ RSS WCHAN STA T TTY TIME COMMAND ... 000 501 2676 898 15 0 4232 1544 wait4 S pts/0 0:00 bash 000 501 2739 2676 18 0 3284 644 - R pts/0 0:00 find / 000 501 2740 2611 16 0 3804 948 wait4 S pts/1 0:00 /bin/bash -

Managing Processes

28

040 501 2741 2740 16 0 3808 1004 wait4 S pts/1 0:00 /bin/bash - 000 501 2742 2741 17 0 3144 1232 - R pts/1 0:00 ps -alx 000 501 2743 2741 17 0 3144 420 pipe_w S pts/1 0:00 tail ... [maxwell@station maxwell]$ ps -alx F UID PID PPID PRI NI VSZ RSS WCHAN STA T TTY TIME COMMAND ... 000 501 2676 898 16 0 4232 1544 wait4 S pts/0 0:00 bash 000 501 2718 2611 15 0 3808 944 wait4 S pts/1 0:00 /bin/bash - 040 501 2719 2718 16 0 3812 1000 wait4 S pts/1 0:00 /bin/bash - 000 501 2720 2719 17 0 3148 1232 - R pts/1 0:00 ps -alx 000 501 2721 2719 17 0 3136 384 - R pts/1 0:00 tail 000 501 2739 2676 17 0 3248 576 - R pts/0 0:00 find / ...

La prioridad del proceso find fluctúa con el tiempo.

El niceness, por el contrario, permanece fijo en 0.

Luego, maxwell utiliza el comando renice para alterar el valor de niceness del proceso.

[maxwell@station maxwell]$ renice 5 2739 [maxwell@station maxwell]$ ps -alx 000 501 2982 898 15 0 4228 1544 schedu S pts/0 0:00 bash 000 501 2739 2676 20 5 3248 576 - RN pts/0 0:00 find / 000 501 3010 2611 16 0 3804 948 wait4 S pts/1 0:00 /bin/bash - 040 501 3011 3010 17 0 3808 1004 wait4 S pts/1 0:00 /bin/bash - 000 501 3012 3011 17 0 3140 1228 - R pts/1 0:00 ps -alx 000 501 3013 3011 17 0 3140 416 pipe_w S pts/1 0:00 tail

Debido a que el valor de niceness se ha incrementado, el proceso tiene valores más altos de prioridad (implicando menos acceso a la CPU por una época de programación).

El nuevo valor de niceness.

Cambiando de parecer, maxwell decide restaurar el niceness a su valor predeterminado de 0.

[maxwell@station maxwell]$ renice 0 2739

Managing Processes

29

renice: 2739: setpriority: Permission denied

Dado que a los usuarios estándar no se les permiten valores de niceness más bajos, el comando falla.

Cambio de prioridades con renice

Al utilizar la opción -u, el usuario maxwell puede cambiar los valores de niceness para todos los procesos al mismo tiempo.

[maxwell@station maxwell]$ ps -lu maxwell F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 515 3031 3028 0 75 0 - 1078 wait4 pts/4 00:00:00 bash 1 S 515 8954 1 0 79 0 - 3313 schedu ? 00:00:00 gvim 0 S 515 8958 3031 1 80 0 - 1078 wait4 pts/4 00:00:00 bash 0 R 515 8984 8958 0 83 0 - 779 - pts/4 00:00:00 ps [maxwell@station maxwell]$ renice 5 -u maxwell 515: old priority 0, new priority 5 [maxwell@station maxwell]$ ps -lu maxwell F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 515 3031 3028 0 85 5 - 1078 wait4 pts/4 00:00:00 bash 1 S 515 8954 1 0 85 5 - 3313 schedu ? 00:00:00 gvim 0 S 515 8958 3031 0 80 5 - 1078 wait4 pts/4 00:00:00 bash 0 R 515 8986 8958 0 86 5 - 779 - pts/4 00:00:00 ps

Ejercicios en línea

Lab Exercise Objetivo: Cambiar las prioridades de los procesos.

Estimated Time: 10 mins.

Especificaciones

1. Ejecutar el siguiente comando en una terminal. 2. [student@station student]$ cat /dev/zero > /dev/null

3. En otra terminal, utilice el comando renice para cambiar el valor de niceness de todos los procesos que le pertenezcan hasta 5 (podría considerar el utilizar el comando pgrep junto con el comando xargs para este paso).

4. Después de completar el último paso, cambie el valor de niceness del proceso cat (iniciado en el paso 1) a 10.

Managing Processes

30

5. Utilice el comando nice para iniciar otro comando cat (de nuevo leyendo /dev/zero redirigido a /dev/null) con el valor de niceness de 15.

Califique su ejercicio con ambas instancias del comando cat aún ejecutándose.

Question 1

1. Un comando cat ejecutándose con el valor de niceness de 10. 2. Un comando cat ejecutándose con el valor de niceness de 15. 3. Todos los otros procesos ejecutados por usted tienen un valor de niceness de 5.

Limpieza

Cuando haya terminado de calificar su ejercicio puede detener todos sus procesos cat con la secuencia de control CTRL -C.

Capítulo 4 Envío de señales

Conceptos clave

• Las señales son una forma de bajo nivel de la comunicación entre procesos que surgen de una variedad de recursos, incluyendo el kernel, la terminal y otros procesos.

• Las señales se distinguen por los números de señales que tienen nombres y usos simbólicos. Los nombres simbólicos para los nombres de señales pueden listarse con el comando kill -l .

• El comando kill envía señales a otros procesos. • Tras recibir una señal, un proceso puede ya sea, ignorarla, reaccionar de un

modo especificado por defecto de kernel o implementar un manejador de señal personalizado.

• Convencionalmente, el número de señal 15 (SIGTERM) se utiliza para solicitar la terminación de un proceso.

• La señal número 9 (SIGKILL ) termina un proceso y no puede anularse. • Los comandos pkill y killall pueden utilizarse para enviar señales a procesos

especificados por nombre de comando o el usuario a quienes pertenecen. • Otras utilidades, tales como top y el Monitor de sistema GNOME, también

pueden utilizarse para enviar señales.

Señales

Linux (y Unix) utiliza señales para notificar procesos de eventos anormales, y como un mecanismo primitivo de comunicación entre procesos. Algunas veces, las señales se conocen como interrupciones de software, porque pueden interrumpir el flujo normal de ejecución de un proceso. El kernel utiliza señales para notificar procesos de conducta

Managing Processes

31

anormal, como si el proceso tratase de dividir un número por cero o tratase de acceder memoria que no le perteneciera.

Los procesos también pueden enviar señales a otros procesos. Por ejemplo, una shell bash podría enviar una señal a un proceso xclock. El proceso receptor sabe muy poco acerca de los orígenes de la señal. No sabe si la señal se originó del kernel o de algún otro proceso, todo lo que sabe es que recibió una señal.

Figure 1. Xclock recibe un señal número 15 de Bash

Sin embargo, hay diferentes sabores de señales. Los diferentes sabores tienen números simbólicos pero también se identifican con números enteros. Los varios números enteros y el nombre simbólico que les son asignados pueden listarse por medio del comando kill -l o los puede encontrar en la página del manual signal(7).

[einstein@station einstein]$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 33) SIGRTMIN 34) SIGRTMIN+1 35) SIGRTMIN+2 36) SIGRTMIN+3 37) SIGRTMIN+4 38) SIGRTMIN+5 39) SIGRTMIN+6 40) SIGRTMIN+7 41) SIGRTMIN+8 42) SIGRTMIN+9 43) SIGRTMIN+10 44) SIGRTMIN+11 45) SIGRTMIN+12 46) SIGRTMIN+13 47) SIGRTMIN+14 48) SIGRTMIN+15 49) SIGRTMAX-15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1

Linux, al igual que varias versiones de Unix, implementa 32 señales "normales". En Linux, las señales se numeran a partir de 32 hasta 63 (que no son estándar entre las varias versiones de Unix) y son señales en "tiempo real" y van más alla del objetivo de este texto.

¿Por qué se envían las señales?

Managing Processes

32

Hay una variedad de razones por las cuales las señales se pueden enviar a un proceso como se ilustra con los siguientes ejemplos.

Excepciones de hardware

El proceso le pidió al hardware realizar alguna operación errónea. Por ejemplo, el kernel enviará un proceso SIGFPE (señal número 8) si realiza una división por 0.

Condiciones del software

Los procesos pueden necesitar ser notificados de alguna condición anormal del software. Por ejemplo, cada vez que muere un proceso, el kernel envía un SIGCHLD (número de señal 17) al padre del proceso. Otro ejemplo, las aplicaciones gráficas X reciben un SIGCHLD (número de señal 17) cada vez que su ventana cambia de tamaño, para poder responder a la nueva geometría.

Interrupciones de terminal

Varias secuencias de control de teclas de la terminal envían señales al proceso de la shell bash. Por ejemplo, CONTROL -C envía un SIGINT (número de señal 2) mientras que CONTROL -Z envía un SIGTSTP (número de señal 20).

Otros procesos

Los procesos pueden elegir enviar señales a cualquier otro proceso perteneciente al mismo usuario. El comando kill está diseñado para hacer justo esto.

Envíar señales: el comando kill

El comando kill se utiliza para enviar señales a otros procesos. Éste espera ser llamado con una opción numérica o simbólica que especifica la señal a enviar y un ID de proceso que especifica el proceso que debería recibirlo. A manera de ejemplo, las siguientes líneas de comando envían un SIGCHLD (número de señal 17) al proceso xclock, el ID del proceso número 8060.

[einstein@station einstein]$ ps PID TTY TIME CMD 7985 pts/5 00:00:00 bash 8060 pts/5 00:00:01 xclock 8061 pts/5 00:00:00 ps [einstein@station einstein]$ kill -17 8060 [einstein@station einstein]$ kill -CHLD 8060 [einstein@station einstein]$ kill -SIGCHLD 8060

Cuando se utiliza el nombre simbólico para especificar una señal, el prefijo “SIG” (compartido por todas las señales) puede ser incluído u omitido.

Recepción de señales

Managing Processes

33

Cuando un proceso recibe una señal puede realizar una de las siguientes tres acciones.

Implementar un manejador de señal predeterminado del kernel

Para cada tipo de señal hay una respuesta predeterminada implementada por el kernel. A cada señal se le asigna una de las siguientes conductas.

• Terminar: El proceso de recepción se cierra. • Ignorar: El proceso de recepción ignora la señal • Núcleo: El proceso de recepción termina, pero bota una imagen de su

memoria en un archivo llamado core en el actual directorio de trabajo del proceso. El archivo core puede ser utilizado por desarrolladores para ayudar a depurar el programa. [1]

• Pare: detenga o (suspenda) el proceso.

La página de manual signal(7) documenta la conducta asignada para cada señal.

Escoja ignorar la señal

Los programadores pueden elegir que su aplicación simplemente ignore señales especificadas.

Escoger implementar un manejador de señal personalizado

Los programadores pueden elegir implementar su propia conducta cuando se recibe una señal específica. La respuesta del programa es completamente determinada por el programador.

A no ser que la documentación del programa diga lo contrario, usted puede asumir que un proceso responderá con la conducta implementada de kernel. Cualquier otra respuesta debe estar documentada.

Uso de señales para terminar procesos

De las 32 señales utilizadas en Linux (y Unix) los usuarios normales en práctica (explícitamente) sólo hacen uso de unas pocas.

Table 1. Señales importantes para usuarios normales

Número Symbol Acción

2 SIGINT Interrumpe (solicita terminar) el proceso. Esta es la señal generada por la secuencia de control CTRL -C.

9 SIGKILL Fuerza el terminar el proceso (esta señal puede no ser anulada por el proceso)

15 SIGTERM Solicita la terminación del proceso.

Managing Processes

34

Número Symbol Acción

20 SIGTSTP Detiene (suspende) el proceso. Esta es una señal generada por la secuencia de control CTRL -Z.

Los usuarios estándar suelen utilizar señales para terminar un proceso (razón del nombre del comando kill ). Por convención, si los programadores quieren implementar la conducta personalizada cuando se apaga (como por ejemplo botando memoria importante al disco, etc), ellos implementan un manejador de señal personalizado de 15 para realizar la acción. El número de señal 9 se maneja especialmente por el kernel y no puede anularse por un manejador de señal personalizado o ser ignorado. Este se reserva como un último recurso, la técnica de nivel de kernel para matar un proceso.

A manera de ejemplo, einstein iniciará un comando cat que en un principio se ejecutaría para siempre. Luego traza el ID del proceso del comando y termina con un SIGTERM.

[einstein@station einstein]$ cat /dev/zero > /dev/null & [1] 8375 [einstein@station einstein]$ ps PID TTY TIME CMD 7985 pts/5 00:00:00 bash 8375 pts/5 00:00:01 cat 8376 pts/5 00:00:00 ps [einstein@station einstein]$ kill -15 8375 [einstein@station einstein]$ [1]+ Terminated cat /dev/zero >/dev/n ull

SIGTERM (número de señal 15) es la señal por defecto para el comando kill , por lo tanto einstein pudo haber utilizado kill 8375 para el mismo efecto. A continuación, einstein repite la secuencia, esta vez enviando un SIGKILL.

[einstein@station einstein]$ cat /dev/zero > /dev/null & [1] 8387 [einstein@station einstein]$ ps PID TTY TIME CMD 7985 pts/5 00:00:00 bash 8387 pts/5 00:00:01 cat 8388 pts/5 00:00:00 ps [einstein@station einstein]$ kill -9 8387 [einstein@station einstein]$ [1]+ Killed cat /dev/zero >/dev/n ull

Alternativas para el comando kill

El uso de señales para controlar procesos es una ocurrencia tan común que las alternativas para usar el comando kill abundan. Las siguientes secciones mencionan unas cuantas.

El comando pkill

Managing Processes

35

En cada uno de los ejemplos anteriores, einstein necesita determinar el ID de un proceso antes de enviar una señal a éste con el comandokill . El comando pkill se puede utilizar para enviar señales a procesos seleccionados por medios más generales. El comando pkill espera la siguiente sintaxis.

pkill [-signal] [OPCIONES] [PATRÓN]

El primer símbolo especifica opcionalmente el número de señal para enviar (por defecto, el número de señal 15). PATTERN es una expresión regular extendida que coincidirá con nombres de comandos. El siguiente cuadro lista las opciones de comando más utilizadas. Los procesos que cumplen con todos los criterios especificados enviarán la señal especificada.

Table 1. Opciones para el comando pkill

Opción Efecto

-n Selecciona únicamente los procesos coincidentes iniciados más recientemente.

-u USER Selecciona procesos pertenecientes al usuario USER.

-t TERM Selecciona procesos controlados por terminal TERM.

De manera conveniente, el comando pkill se omite a si mismo y la shell que lo inició cuando mataba todos los proceso pertenecientes a un usurario particular o a una terminal. Considere el siguiente ejemplo.

[maxwell@station maxwell]$ ps PID TTY TIME CMD 10353 pts/4 00:00:00 bash 10396 pts/4 00:00:00 xclock 10397 pts/4 00:00:03 mozilla-bin 10422 pts/4 00:00:00 ps [maxwell@station maxwell]$ pkill -u maxwell [1]- Terminated xclock [maxwell@station maxwell]$ ps PID TTY TIME CMD 10353 pts/4 00:00:00 bash 10424 pts/4 00:00:00 ps [2]+ Exit 15 mozilla

Observe que aunque la shell bash se clasifica como un proceso perteneciente al usuario maxwell, ésta sobrevivió.

El comando killall

Igual que pkill , el comando killall envía señales a procesos especificados por el nombre de comando. El comando killall soporta las siguientes opciones.

Table 1. Opciones para el comando killall

Managing Processes

36

Opción Efecto

-i, --interactive

De modo interactivo pregunta al usuario antes de enviar la señal a un proceso.

-w, --wait Espera hasta que todos los procesos estén muertos antes de retornar.

El Monitor del sistema

La aplicación del Monitor de sistema GNOME, presentada en una lección anterior, también puede utilizarse para enviar señales a los procesos. Al hacer click derecho en un proceso, un menú emergente le permite al usuario seleccionar End Process, el cual tiene el efecto de entregar un SIGTERM al proceso. ¿Qué hace la opción del menú Matar proceso?

Figure 1. Terminación de procesos mediante el monitor del sistema.

El comando top

El comando top puede también utilizarse para entregar señales a procesos. Al utilizar la tecla K , aparece el siguiente diálogo encima de la lista de procesos, permitiéndole al usuario especificar qué procesos ID deberían recibir la señal y qué señal entregar.

PID to kill: 4859 Kill PID 4859 with signal [15]: 9

Ejemplos

Uso de señales para terminar procesos

Las señales suelen ser la única forma de terminar procesos que están siendo manejados por una línea de comando de shell. Por ejemplo, los clientes (aplicaciones) gráficos X pueden matarse al entregar un SIGTERM al proceso apropiado. En el siguiente ejemplo, el usuario maxwell está ejecutando el navegador de red Mozilla y el reloj gráfico xclock. Utiliza el comando pgrep para localizar sus ID de procesos, mata el primero mediante el comando kill y el segundo mediante el comando pkill .

[maxwell@station maxwell]$ pgrep -lu maxwell 2112 bash 2146 mozilla-bin 2155 mozilla-bin 2156 mozilla-bin 2157 mozilla-bin 2329 mozilla-bin 2597 xclock [maxwell@station maxwell]$ kill 2146 [maxwell@station maxwell]$ pkill xclock [1]- Exit 15 mozilla

Managing Processes

37

[2]+ Terminated xclock [maxwell@station maxwell]$ pgrep -lu maxwell 2112 bash

Pero, ¡espere! Hay una forma diferente para terminar aplicaciones gráficas aparte del envío de señales. Solamente haga click en la casilla "cerrar" en la esquina superior derecha o seleccione Cerrar en menú desplegable en la esquina superior izquierda. Entre bastidores, esta es precisamente la labor de estas acciones: entregar una señal SIGTERM a una aplicación adjunta.

Uso de señales para matar procesos

Cada vez que sea posible la señal SIGTERM debería utilizarse para terminar procesos. Sin embargo, algunas veces, los procesos están "encerrados" y completamente insensibles, incluso para las señales SIGTERM. En estos casos, la señal SIGKILL (número de señal 9) puede utilizarse como un último recurso. La señal SIGKILL mata un proceso en el kernel sin ninguna interacción con el proceso mismo.

A continuación, maxwell intenta terminar una simulación física (el proceso sim) con la señal por defecto SIGTERM. Por alguna razón, el proceso es insensible por lo tanto maxwell lo mata con la señal SIGKILL.

[maxwell@station maxwell]$ pgrep -lu maxwell 2112 bash 4489 sim [maxwell@station maxwell]$ pkill sim [maxwell@station maxwell]$ pgrep -lu maxwell 2112 bash 4489 sim [maxwell@station maxwell]$ pkill -KILL sim [1]+ Killed sim [maxwell@station maxwell]$ pgrep -lu maxwell 2112 bash

¡Hágalo que pare!

La combinación de la habilidad de pkill para seleccionar todos los procesos pertenecientes a un usuario particular, y la señal SIGKILL de bajo nivel letal, conforman una técnica conveniente para que un usuario mate todos los procesos que puedan estar ejecutándose en la máquina local.

A continuación, maxwell observa primero cuántos procesos está ejecutando en la máquina local. Luego mata todos los procesos.

[maxwell@station maxwell]$ pgrep -u maxwell | wc -l 22 [maxwell@station maxwell]$ pkill -KILL -u maxwell

Como resultado, maxwell se saca de la máquina (matando su propia sesión X o inicio de sesión de consola virtual) y debe iniciar sesión otra vez.

Managing Processes

38

Ejercicios en línea

Lab Exercise Objetivo: Terminar la ejecución de procesos de manera efectiva.

Estimated Time: 10 mins.

Especificaciones

1. Crear un script corto de shell llamado ~/bin/kill_all_cats y hacerlo ejecutable. Cuando se ejecute, el guión debería matar todos los procesos cat en ejecución.

2. En una terminal, iniciar un proceso cat mediante la siguiente línea de comandos. Deje el proceso en ejecución mientras califica su ejercicio (pero no se sorprenda si no está en ejecución cuando termine).

3. [student@station student]$ cat /dev/zero > /dev/null

Deliverables

Question 1

1. Un script de shell llamado ~/bin/kill_all_cats que al ejecutarse, entregue

una señal SIGTERM a todas las instancias actuales en ejecución del comando cat.

2. Un proceso cat en ejecución.

Capítulo 5 Control de trabajo

Conceptos clave

• La shell bash permite a los comandos ejecutarse en segundo plano como "trabajos".

• La shell bash permite a un trabajo ejecutarse en segundo plano y puede tener múltiples trabajos en segundo plano.

• El comando jobs listará todos los trabajos en segundo plano. • La secuencia de teclas CONTROL-Z suspenderá y enviará a segundo plano el

actual trabajo que se encuentra en primer plano. • El comando bg reanuda un trabajo de segundo plano. • El comando fg trae un trabajo de segundo plano a primer plano.

Managing Processes

39

Los temas tratados en este cuaderno hasta el momento, es decir la información sobre listado de procesos, el cambio de un valor niceness de un proceso y el envío de señales a procesos son características compartidas por todos los procesos, ya sean iniciados desde una línea de comandos de shell o de otro modo. A diferencia de estos temas anteriores, el tema que nos resta, control de trabajo tiene que ver el manejo de procesos iniciados desde un intérprete de comandos de una shell interactiva y se enfocará en la shell bash.

Ejecución de comandos en el primer plano

Cuando se ejecuta un comando desde un intérprete de comandos shell bash, a no ser que usted especifique lo contrario, el comando se ejecuta en el primer plano. La shell bash espera que el comando de primer plano termine antes de expedir otro intérprete de comandos y cualquier cosa escrita con el teclado se lee generalmente como la stdin para este comando. Todo esto debería sonar familiar porque los comandos utilizados hasta el momento se han ejecutado en el primer plano.

Ejecución de comandos en segundo plano como trabajos

En contraste, cualquier comando que usted especifique puede también ejecutarse en el segundo plano, adjuntándole el signo (“&”) a la línea de comandos. Por lo general, sólo los comandos de larga ejecución que no requieren entradas desde el teclado y no generan grandes cantidades de salida son apropiados para un segundo plano. Cuando la shell bash envía a segundo plano un comando, el comando se conoce como un trabajo y se le asigna un número de trabajo.

En el siguiente ejemplo, einstein está realizando una búsqueda de los archivos que mayores de 1 megabyte en tamaño en su sistema de archivos. Dado que espera este comando para ejecutar por un tiempo, dirige la stdout a un archivo, bota la stderr y la ejecuta como un trabajo de segundo plano.

[einstein@station einstein]$ find / -size +1024k > bigfiles.txt 2> /dev/null & [1] 7022

Después de iniciar el trabajo en el segundo plano, la shell bash reporta dos partes de información a einstein. La primera es el número de trabajo reportado entre paréntesis cuadrados. La segunda es el ID del proceso del trabajo de segundo plano. En este caso, el trabajo es el número de trabajo 1 y el ID del proceso del comando find es 7022.

Mientras que este comando se ejecuta en el segundo plano, einstein decide buscar los archivos que le pertenecen y que no ha modificado en dos semanas. Escribe el comando apropiado find y de nuevo envía a segundo plano el trabajo.

[einstein@station einstein]$ find / -user einstein -and -mtime +14 > oldfiles.txt 2> /dev/null & [2] 7023 [1] Exit 1 find / -size +1M >big files.txt 2>/dev/null

Managing Processes

40

De nuevo, bash reporta el número de trabajo (2) y el ID del proceso del segundo comando find (7023).

El segundo mensaje de shell bash está notificando a einstein el número de trabajo que se ha terminado. La shell bash reporta que ésta ha salido con un código de retorno de 1 (opuesto a ser matado por una señal) y revisualiza la línea de comando para recordar a einstein lo que ha ejecutado. La shell bash no reporta inmediátamente la muerte de los trabajos, sino espera hasta la próxima vez que interprete una línea de comandos.

Cuando einstein ha digerido todo esto sospecha que su segundo trabajo también ha terminado. Simplemente, pulsa la tecla ENTER (para que bash "interpretará" la línea de comandos vacía). Igualmente, la shell bash reporta su nuevo número de trabajo 2.

[einstein@station einstein]$ [2]+ Exit 1 find / -user einstein -and -mtime +14 >oldfiles.tx t 2>/dev/null

Administración de múltiples trabajos

El usuario einstein, al igual que maxwell, suele realizar cálculos físicos que toman mucho tiempo para ejecutar. Inicia varias versiones de la simulación enviándolas al segundo plano.

[einstein@station einstein]$ ls bin sim_a sim_b sim_c sim_d [einstein@station einstein]$ ./sim_a & [1] 7309 [einstein@station einstein]$ ./sim_b & [2] 7311 [einstein@station einstein]$ ./sim_c & [3] 7313 [einstein@station einstein]$ ./sim_d & [4] 7315

Listado de trabajos actuales con jobs

El usuario einstein puede utilizar el comando incorporado jobs para reportar todos sus trabajos en ejecución.

[einstein@station einstein]$ jobs [1] Running ./sim_a & [2] Running ./sim_b & [3]- Running ./sim_c & [4]+ Running ./sim_d &

Cada uno de sus trabajos de segundo plano son listados junto con el número de trabajo. El trabajo más reciente se conoce como el trabajo actual y es representado por el comando jobs con un “+”.

Traer un trabajo al primer plano con fg

Managing Processes

41

Un trabajo de segundo plano puede traerse al primer plano con el comando incorporado fg. El comando fg espera un número de trabajo como un argumento o si ninguno es provisto pondrá el trabajo actual en primer plano.

[einstein@station einstein]$ fg 3 ./sim_c

Ahora, el trabajo sim_c está ejecutándose en el primer plano. Como consecuencia, la shell no generará ningún intérprete de comandos cuando el proceso esté en ejecución.

Suspensión del trabajo de primer plano con CONTROLZ

Previamente, se introdujo la secuencia CONTROL -Z como un método para suspender procesos. Ahora, al observar de cerca la salida de la shell bash cuando einstein suspende el comando de primer plano, vemos que la shell bash trata como un trabajo a cualquier proceso de primer plano suspendido.

[einstein@station einstein]$ fg 3 ./sim_c CTRL- Z [3]+ Stopped ./sim_c [einstein@station einstein]$ jobs [1] Running ./sim_a & [2] Running ./sim_b & [3]+ Stopped ./sim_c [4]- Running ./sim_d & [einstein@station einstein]$ ps u USER PID %CPU %MEM VSZ RSS TTY STAT S TART TIME COMMAND einstein 6987 0.0 0.3 4316 976 pts/8 S 1 5:56 0:00 -bash einstein 7309 0.0 0.3 4112 1004 pts/8 S 1 6:20 0:00 /bin/bash ./sim_a einstein 7311 0.0 0.3 4112 1004 pts/8 S 1 6:20 0:00 /bin/bash ./sim_b einstein 7313 0.0 0.3 4112 1004 pts/8 T 1 6:20 0:00 /bin/bash ./sim_c einstein 7315 0.0 0.3 4112 1000 pts/8 S 1 6:20 0:00 /bin/bash ./sim_d einstein 7446 0.0 0.2 2616 660 pts/8 R 1 6:34 0:00 ps u

Cuando está suspendido (o para utilizar la terminología de shell, detenido), el proceso recibe el número de trabajo (si es que aún no lo tiene) y se envía al segundo plano. El comando jobs reporta el trabajo como un trabajo "detenido" y el comando ps confirma que está detenido.

Reiniciar un trabajo detenido en el segundo plano

Un trabajo detenido puede reiniciarse en el segundo plano con el comando incorporado bg. Al igual que el comando fg, el comando bg espera un número de trabajo como un argumento o si no se provee ninguno entonces se utiliza el trabajo actual.

Managing Processes

42

A continuación, einstein reinicia su trabajo detenido en el segundo plano.

[einstein@station einstein]$ bg 3 [3]+ ./sim_c & [einstein@station einstein]$ jobs [1] Running ./sim_a & [2] Running ./sim_b & [3]- Running ./sim_c & [4]+ Running ./sim_d &

Ahora el número de trabajo 3 está otra vez en estado de ejecución.

Matar trabajos

El comando kill , utilizado para entregar señales para procesos se implementa como un comando incorporado de shell, (confusamente, también se encuentra otra versión en el sistema de archivos /bin/kill . Probablemente usted está utilizando la versión de shell incorporada). Como resultado, está consciente de los trabajos que la shell está administrando.

Cuando se especifica qué proceso debería recibir una señal, el número de trabajo del proceso (si lo hay) puede especificarse en vez de su ID de proceso. Para distinguir los dos, los números de trabajo están precedidos por un caracter de porcentaje (“%”) como se ilustra en el siguiente ejemplo.

[einstein@station einstein]$ jobs [1] Running ./sim_a & [2] Running ./sim_b & [3]- Running ./sim_c & [4]+ Running ./sim_d & [einstein@station einstein]$ kill 2 -bash: kill: (2) - Operation not permitted [einstein@station einstein]$ kill %2 [einstein@station einstein]$ [2] Terminated ./sim_b [einstein@station einstein]$ jobs [1] Running ./sim_a & [3]- Running ./sim_c & [4]+ Running ./sim_d &

Aquí einstein erróneamente utilizó la sintaxis para especificar un ID de proceso, en vez del número de trabajo. Puesto que él no posee su propio proceso con el ID de proceso número 2, el comando falla.

Aquí, einstein utilizó la sintaxis correcta para especificar un número de trabajo y la señal fue enviada al proceso sim_b.

Resumen

El siguiente cuadro resume los comandos y técnicas para administrar trabajos dentro de la shell bash.

Managing Processes

43

Table 1. Administración de trabajos en la shell bash

Comando Acción

trabajos Lista todos los trabajos

fg [N] Trae el trabajo N de segundo plano al primer plano (por defecto, el trabajo de segundo plano "actual").

CTRL -Z Suspende y envía al segundo plano el actual comando de primer plano

bg [N] Inicia el trabajo de segundo plano detenido N (por defecto, el trabajo "actual"en segundo plano).

kill % N Termina el trabajo de segundo plano N (enviando la señal SIGTERM).

Ejemplos

Decidir enviar a segundo plano un comando ejecutándose en el primer plano

La discusión mencionó que los comandos se pueden iniciar en el segundo plano, agregando un signo “&” a la línea de comandos. A continuación, einstein inicia un comando en el primer plano y luego, dándose cuenta que le tomaría mucho tiempo completar, deseá haberlo iniciado en el segundo plano.

[einstein@station einstein]$ ./sim_a

Con el fin de enviar al segundo plano el comando, primero lo suspende con la secuencia de control CONTROL -Z, la cual lo abandona como un trabajo de segundo plano detenido. Luego reinicia el trabajo en el segundo plano mediante bg.

[einstein@station einstein]$ ./sim_a CTRL-Z [1]+ Stopped ./sim_a [einstein@station einstein]$ bg [1]+ ./sim_a & [einstein@station einstein]$

Uso de CONTROLC para matar un trabajo en segundo plano.

Como una alternativa para el comando kill , la siguiente técnica se utiliza para cancelar trabajos enviados al segundo plano. Primero, se trae el trabajo al primer plano con el comando y luego se mata con la secuencia CONTROL -C.

[einstein@station einstein]$ jobs [1] Running ./sim_a & [2]- Running ./sim_b & [3]+ Running ./sim_c & [einstein@station einstein]$ fg 2 ./sim_b CTRL-C

Managing Processes

44

[einstein@station einstein]$ jobs [1]- Running ./sim_a & [3]+ Running ./sim_c &

Ejercicios en línea

Lab Exercise Objetivo: Uso del control de trabajo bash para administrar trabajos múltiples.

Estimated Time: 10 mins.

Especificaciones

1. Inicie los siguientes cuatro comandos, colocando a cada uno en el segundo plano.

2. ls -R / | grep "*.conf" > lsconf 2>/dev/null 3. cat /dev/zero > /dev/null 4. find / -name "[Aa]*[Cc]*[Ff]*" 5. sleep 100000

6. Mediante los comandos de control de trabajos y las secuencias comunes de control, parar (suspender) los trabajos ls y find .

Deliverables

Question 1

1. Cuatro trabajos enviados al segundo plano administrados por la shell bash. Los

trabajos cat y sleep deberían estar ejecutándose, mientras que los trabajos find y ls deberían suspenderse.

Limpieza

Después de haber calificado su ejercicio, utilice el comando kill (o la combinación fg/ CONTROL -C) para matar todos los cuatro trabajos.

Capítulo 6 Programación de tareas retrasadas: at

Conceptos clave

• El comando at puede someter comandos para que se ejecuten más tarde.

Managing Processes

45

• El comando batch puede emitir comandos para que se ejecuten cuando la carga de las máquinas sea baja.

• Los comandos pueden escribirse directamente o someterse como un script. • la stdout de los trabajos at se envía por correo al usuario. • Los comandos atq y atrm se utilizan para examinar y quitar trabajos

actualmente programados.

Demonios

Antes de abordar el comando at directamente comenzamos con una corta discusión de un concepto común en Unix: los demonios.

Con un nombre inspirado por Daemon del físico Maxwell, los demonios Unix son procesos que se ejecutan en el segundo plano, separados de una terminal, realizan tareas que no suelen estar relacionadas con el teclado de un usuario. Los demonios suelen asociarse con servicios de red tales como el servidor de red (httpd ) o el servidor FTP (vsftpd). Otros demonios administran tareas del sistema tal como el demonio de inicio de sesión (syslogd) y el demonio administrador de potencia (apmd). Esta y la siguiente lección describirán dos demonios que permiten a los usuarios retrasar tareas (atd), o ejecutar comandos en intervalos fijos (crond). Hasta el momento, usted habrá notado una convención para nombres: los programas diseñados para ejecutarse como demonios suelen terminar con la letra d.

Los demonios son procesos como cualquier otro proceso. Suelen iniciar como parte de la secuencia de un sistema de arranque o por el usuario root, por lo tanto, usted nunca sabría que están ahí a menos que los busque.

[elvis@station elvis]$ ps aux | grep crond root 890 0.0 0.0 1572 132 ? S 0 9:57 0:00 crond elvis 5035 0.0 0.2 3572 640 pts/4 S 1 6:17 0:00 grep crond [elvis@station elvis]$ ps aux | grep atd daemon 4730 0.0 0.2 1420 532 ? S 1 5:42 0:00 /usr/sbin/atd elvis 5037 0.0 0.2 3572 640 pts/4 S 1 6:17 0:00 grep atd

Algunos demonios se ejecutan como el usuario root, mientras otros adquieren la identidad de otro usuario de sistema por asuntos de seguridad. Arriba, el demonio crond se está ejecutando como root pero el demonio atd está ejecutándose como el demonio de usuario.

El demonio atd

El demonio atd le permite a los usuarios someter trabajos para ser realizados más tarde, tal como a las "at 2:00am". Para utilizar el demonio atd, éste debe estar ejecutándose.

Managing Processes

46

Los usuarios pueden confirmar que atd se está ejecutando simplemente al examinar la lista de procesos en ejecución:

[madonna@station madonna]$ ps aux | grep atd daemon 4730 0.0 0.2 1420 532 ? S 1 5:42 0:00 /usr/sbin/atd madonna 5570 0.0 0.2 3572 640 pts/2 S 1 6:43 0:00 grep atd

Observe que la séptima columna especifica con qué terminal se asocia un proceso. Para el comando grep de blondie, la terminal es pts/2 , la cual probablemente se refiere a una shell de red o a una terminal gráfica dentro de una sesión X. Observe que el demonio atd no tiene terminal asociada. Una de las características de un demonio es que quita su asociación con la terminal que la inició.

Envío de trabajos con at

El comando at se utiliza para someter trabajos al demonio atd para que se ejecuten en una hora específica. Los comandos que se van a ejecutar son sometidos ya sea como script (con la opción -f) o escritos directamente via la stdin. La salida estándar del comando se envía por correo al usuario.

at [[-f filename] | [-m]] TIME

Opción Efecto

-f filename

ejecuta el script especificado por el nombre de archivo

-m Notifica al usuario por correo electrónico cuando se ejecuta, incluso si no hay salida.

La hora del día se puede especificar utilizando HH:MM, con el sufijo "am" o "pm". Los términos en inglés "midnight", "noon", y "teatime" también pueden utilizarse. Igualmente, mediante varios formatos incluyendo MM/DD/YY. (mes/día/año/). Para mayor información refiérase a la página del manual at(1).

El luchador hogan desearía imprimir un archivo con todo el correo que ha recibido de sus admiradores, fanmail.txt . Está un poco preocupado porque comparte la impresora con ventura, quien también utiliza mucho la impresora. Como quiere evitar peleas, decide demorar su trabajo de impresión hasta las 2:00 de la mañana.

[hogan@station hogan]$ at 2:00 am warning: commands will be executed using (in order) a) $SHELL b) login shell c) /bin/sh at> lpr fanmail.txt at> CTRL-D job 7 at 2003-06-17 02:00

Managing Processes

47

Dado que hogan no utilizó la opción -f, el comando at le pidió teclear sus comandos mediante la stdin (el teclado). Afortunadamente, hogan sabía que cuando la secuencia CONTROL -D, se escribe directamente desde una terminal indica un "fin de archivo". Como alternativa pudo haber entubado el comando dentro de la stadin directamente:

[hogan@station hogan]$ echo "lpr fanmail" | at 2:00 am warning: commands will be executed using (in order) a) $SHELL b) login shell c) /bin/sh job 7 at 2003-06-17 02:00

Luego, hogan confirma que su trabajo se ha registrado con atq.

[hogan@station hogan]$ atq 7 2003-06-17 02:00 a hogan

Por último, hogan recuerda que ventura está en vacaciones por lo tanto puede imprimir la correspondencia de sus admiradores sin ningún problema. Decide cancelar su trabajo at e imprimir el archivo directamente.

[hogan@station hogan]$ atrm 7 [hogan@station hogan]$ atq [hogan@station hogan]$ lpr fanmail.txt

Retraso de tareas con batch

El comando batch, al igual que el comando at, se utiliza para retrasar tareas. A diferencia del comando at, batch no ejecuta el comando at en un tiempo específico, sino que espera hasta que el sistema se desocupe de otras tareas a cualquier hora. Si la máquina no está ocupada cuando se somete un trabajo, el trabajo podría ejecutarse inmediatamente. El demonio atd controla el loadavg (promedio de carga) del sistema y espera que baje por debajo de 0.8 antes de ejecutar el trabajo.

El comando batch tiene una sintaxis idéntica al comando at, donde los trabajos pueden ser especificados con la stadin o sometidos como un lote con la opción -f. Si la hora se especifica, el batch se demorará observando la máquina hasta el tiempo especificado. En ese momento batch comenzará a controlar el loadavg del sistema, y ejecutará el trabajo cuando el sistema no esté de otra manera ocupado.

Resumen de los comandos at

El siguiente cuadro resume el comando utilizado al registrar trabajos con el demonio atd.

Table 1. Comandos relacionados con el servicio at

Managing Processes

48

command uso

atd El demonio que ejecuta trabajos sometidos. Los usuarios no utilizan el comando atd directamente.

at Somete trabajos al demonio atd para que se ejecuten en un tiempo específico.

batch Somete trabajos al demonio atd para que se ejecuten cuando el sistema no esté ocupado.

atq Lista trabajos en espera con el demonio atd.

atrm Cancela un trabajo en espera con el demonio atd antes de ejecutarse.

Ejemplos

Someter un trabajo at como un archivo

El usuario hogan ha desarrollado ahora el hábito de imprimir su correspondencia de sus admiradores a las 2:00 de la mañana. También ha descubierto el comando enscript, el cual reformatea archivos de texto imprimiéndolos "2up" (dos páginas de texto impresas por páginas) y representa la página impresa con encabezados informativos y pies de página. Después de una corta experiencia desarrolla la siguiente opción para formatear la página a su gusto: enscript -r2 -G --header="Fan Mail" --borders fanmail.txt .

Dado que hogan no quiere teclear este comando y todas las opciones a cada rato, crea un guión corto con el (o los) comando(s) que desearía ejecutar en un archivo llamado fanmail.at :

[hogan@station hogan]$ cat fanmail.at enscript -r2 -G --header="Fan Mail" --borders fanm ail.txt

Ahora, cuando hogan quiere someter a impresión su correspondencia de la fanaticada puede simplemente especificar el script a at con la opción -f.

[hogan@station hogan]$ at -f fanmail.at 2:00 am warning: commands will be executed using (in order) a) $SHELL b) login shell c) /bin/sh job 11 at 2003-06-18 02:00 [hogan@station hogan]$ atq 11 2003-06-18 02:00 a hogan

Examen de la sintaxis Spool

El usuario ventura ha notado que hogan tiene la costumbre de imprimir la correspondencia de sus admiradores a las 2:00 am y como un chiste práctico decide someter un trabajo de su propiedad. Crea el archivo bogus_fanmail.txt , que falsifica correspondencia no muy elogiosa de sus fanáticos. Somete un trabajo que imprimirá el archivo a la 1:59 am confiando que hogan no notará la inserción cuando recoja los papeles de la impresora en la mañana.

Managing Processes

49

[ventura@station ventura]$ echo "lpr bogus_fanmail.txt" | at 1:59 am warning: commands will be executed using (in order) a) $SHELL b) login shell c) /bin/sh job 12 at 2003-06-18 01:59 [ventura@station ventura]$ atq 12 2003-06-18 01:59 a ventura

En cierto punto más adelante, el administrador del sistema de la máquina actuando como root, observa los dos trabajos at en espera.

[root@station at]# atq 11 2003-06-18 02:00 a hogan 12 2003-06-18 01:59 a ventura

Curioso por lo que ventura piensa hacer, root fisgonea dentro del directorio spool de at. Examina el contenido de su nombre de archivo spool llamado de forma críptica a0000c010c8887 , el cual pertenece al usuario ventura.

[root@station at]# ls -l total 12 -rwx------ 1 hogan hogan 1480 Jun 17 1 2:37 a0000b010c8888 -rwx------ 1 ventura ventura 1459 Jun 17 1 3:08 a0000c010c8887 drwx------ 2 daemon daemon 4096 Jun 16 1 7:24 spool [root@station at]# cat /var/spool/at/a0000c010c8887 #!/bin/sh # atrun uid=511 gid=511 # mail ventura 0 umask 2 HOSTNAME=bowe-lt.rdu.redhat.com; export HOSTNAME HISTSIZE=1000; export HISTSIZE USER=ventura; export USER LOGNAME=ventura; export LOGNAME ... LESSOPEN=\|/usr/bin/lesspipe.sh\ %s; export LESSOPE N G_BROKEN_FILENAMES=1; export G_BROKEN_FILENAMES XAUTHORITY=/home/ventura/.xauthqEj97Q; export XAUTH ORITY cd /home/ventura || { echo 'Execution directory inaccessible' >& 2 exit 1 } lpr bogus_fanmail.txt

(En este listado largo, se han borrado varias líneas y se han remplazado por "...".)

root observa los siguientes aspectos de la conducta del script:

El archivo es un script de shell y debido a sus permisos pudo ejecutarse directamente.

La primera acción del script es la de establecer la umask del proceso a la umask de shell que sometió el trabajo.

La segunda acción es inicializar una colección de variables de entorno para imitar

Managing Processes

50

el entorno de shell que sometió el trabajo.

La tercera acción es cambiar el directorio actual del proceso al directorio actual de trabajo de la shell que sometió el trabajo.

Por último, después de toda esta inicialización, el guión está listo para ejecutar el trabajo sometido, en este caso lpr bogus_fanmail.txt.

Al almacenar toda esta información con el trabajo sometido, el demonio atd es capaz de reconstruir el entorno de ventura cuando se envía el trabajo. Si el trabajo enviado crea nuevos archivos, los archivos tendrían los permisos esperados, porque el guión crearía la umask apropiada. Si cualquiera de los comandos iniciados por el script dependiera de las variables de entorno, el entorno se establecería como se espera y así sucesivamente.

Ejercicios en línea

Someter un trabajo para una ejecución posterior

Ejercicio Objetivo: Utilizar el servicio atd para retrasar la ejecución de una tarea.

Estimated Time: 10 mins.

Especificaciones

Usted ha tenido dificultades tratando de recordar qué día es y por lo tanto quisiera enviarse una copia del calendario actual para verlo como primera cosa en la mañana. Envía un trabajo que simplemente ejecuta el comando cal para las 3:45 de la mañana. Asegúrese que es el único trabajo programado con esa facultad.

Deliverables

Question 1

1. Un trabajo en espera que generará la salida del comando cal a las 3:45 de la

mañana.

Capítulo 7 Programación de tareas periódicas: cron

Conceptos clave

• La utilidad cron se utiliza para programar tareas recurrentes. • El comando crontab provee un frontend para editar archivos crontab.

Managing Processes

51

• El archivo crontab utiliza 5 campos para especificar la información de temporización.

• la stdout de trabajos cron se envía por correo al usuario.

Ejecución de tareas periódicas

A menudo, las personas encuentran que están realizando tareas en forma sistemática. En la administración de sistemas dichas tareas podrían incluir quitar archivos viejos o no utilizados del directorio /tmp o comprobar si un archivo que está recolectando mensajes de registro no ha crecido demasiado. Otros usuarios podrían hallar que son tareas propias el chequear archivos grandes que ya no se estén utilizando o chequear un sitio web para ver si hay algún anuncio.

El servicio cron permite a los usuarios configurar comandos para que se ejecuten con regularidad tal como cada 10 minutos, una vez cada jueves, o dos veces al mes. Los usuarios especifican qué comandos deberían ejecutarse y a qué horas mediante el comando crontab para configurar su "cuadro cron". Las tareas se administran por el demonio tradicional de Linux (y Unix), el demonio crond.

El servicio cron

El demonio crond es el demonio que realiza tareas periódicamente en nombre del sistema o de usuarios individuales. El demonio suele iniciarse cuando el sistema arranca, por lo tanto, la mayoría de usuarios lo pueden ignorar. Al listar todos los procesos y buscar crond puede confirmar si el demonio crond está en ejecución.

[hogan@station hogan]$ ps aux | grep crond root 891 0.0 0.0 1572 128 ? S J un17 0:00 crond hogan 8118 0.0 0.2 3576 644 pts/2 S 1 0:15 0:00 grep crond

Si el demonio crond no está ejecutándose, su administrador de sistema necesitaría iniciar el servicio crond como root.

Sintaxis crontab

Los usuarios especifican los trabajos que se van a ejecutar y cuándo se van a ejecutar, al configurar un archivo conocido como el "cuadro cron" a menudo abreviado en inglés "crontab". Un ejemplo de archivo crontab aparece a continuación.

# set the default language to be english LOCALE=en_US 05 * * * * procinfo 15 04 * * * find $HOME -size +100k 25 04 1 * * echo "Pay your bills"

Managing Processes

52

35 04 14 3 * echo "Beware the Ides of March" | ma il -s "a warning" julius 45 04 * * 1 find $HOME -atime +30 | lpr

Un archivo crontab es un archivo de configuración basado en línea, cada línea realiza una de tres funciones:

Comentarios

Todas las líneas cuyo primer caracter (no espacio) es # se consideran comentarios y se ignoran.

Variables de entorno

Todas las líneas que tienen la forma nombre = valor se utilizan para definir variables de entorno.

Comandos cron

Cualquier otra línea (no en blanco) se considera un comando cron, el cual consta de seis campos descritos a continuación.

Las líneas del comando cron constan de seis campos separados de espacios en blanco. Los primeros 5 campos se utilizan para especificar cuándo ejecutar el comando y el sexto campo se utiliza para especificar el comando a ejecutar (compuesto de todo después del quinto campo). Los primeros cinco campos especifican la siguiente información:

,----------------> minute | ,-------------> hour | | ,----------> day of month | | | ,-------> month (1=January, 2=February, ...) | | | | ,----> day of week (0=Sunday, 1=Monda y, ...) | | | | | ,-> command to run | | | | | | 25 04 1 * * echo "Pay your bills"

Cada uno de los primeros cinco campos debe llenarse con un símbolo mediante la siguiente sintaxis:

símbolo significado ejemplo interpretación (si se utiliza en el primer campo)

* cada vez * cada minuto

n a la hora especificada 10 cada hora y 10 minutos

n, n, ... a cualquiera de las horas especificadas

22,52 a cada hora pasados los 22 y 52 minutos

Managing Processes

53

símbolo significado ejemplo interpretación (si se utiliza en el primer

campo)

*/n cada n hora */15 cada 15 minutos (a los 0, 15, 30 y 45 minutos después de la hora)

Uso del comando crontab

Los usuarios rara vez administran su archivo crontab directamente (o incluso saben dónde se almacena), en cambio, utilizan el comando crontab para editar la lista o quitarla.

crontab {[-e] | [-l] | [-r]}

crontab ARCHIVO

Edita o quita el archivo crontab actual o remplaza el archivo actual crontab con FILE.

Opción Efecto

-e modifica el archivo actual

-l lista el archivo actual

-r quita el archivo actual

En la siguiente secuencia de comandos, hogan utilizará el comando crontab para administrar su configuración crontab. Primero lista su configuración actual crontab en la pantalla, luego lista el archivo actual otra vez almacenando la salida dentro del archivo mycopy .

[hogan@station hogan]$ crontab -l # DO NOT EDIT THIS FILE - edit the master and reins tall. # (/tmp/crontab.9212 installed on Wed Jun 18 11:46: 36 2003) # (Cron version -- $Id: 040_crontab.dbk,v 1.1 2005/ 03/21 05:24:29 brads Exp $) # set the default language to be english. LOCALE=en_US 05 * * * * procinfo 15 04 * * * find $HOME -size +100k 25 04 1 * * echo "Pay your bills" 35 04 14 3 * echo "Beware the Ides of March" | ma il -s "a warning" julius 45 04 * * 1 find $HOME -atime +30 | lpr [hogan@station hogan]$ crontab -l > mycopy

Luego, hogan quita su configuración de crontab actual. Cuando trata de nuevo de listar la configuración, se le informa que no existe ninguna configuración actual.

[hogan@station hogan]$ crontab -r

Managing Processes

54

[hogan@station hogan]$ crontab -l no crontab for hogan

Con el fin de restaurar su configuración cron, hogan utiliza el comando crontab una vez más, esta vez especificando el archivo mycopy como un argumento. Tras listar su configuración una vez más, halla que su actual configuración fue leída desde el archivo mycopy .

Un poco molesto, el banner se ha duplicado en el proceso, ¿sabe por qué?

[hogan@station hogan]$ crontab mycopy [hogan@station hogan]$ crontab -l # DO NOT EDIT THIS FILE - edit the master and reins tall. # (mycopy installed on Wed Jun 18 11:47:00 2003) # (Cron version -- $Id: 040_crontab.dbk,v 1.1 2005/ 03/21 05:24:29 brads Exp $) # DO NOT EDIT THIS FILE - edit the master and reins tall. # (/tmp/crontab.9212 installed on Wed Jun 18 11:46: 36 2003) # (Cron version -- $Id: 040_crontab.dbk,v 1.1 2005/ 03/21 05:24:29 brads Exp $) # set the default language to be english. LOCALE=en_US 05 * * * * procinfo 15 04 * * * find $HOME -size +100k 25 04 1 * * echo "Pay your bills" 35 04 14 3 * echo "Beware the Ides of March" | ma il -s "a warning" julius 45 04 * * 1 find $HOME -atime +30 | lpr [hogan@station hogan]$ rm mycopy

Modificar archivos crontab ya establecidos

Los usuarios suelen modificar sus archivos crontab mediante crontab -e. El comando crontab abrirá la configuración crontab dentro del editor predeterminado del usuario. Cuando el usuario termina de modificar el archivo y sale del editor, el contenido modificado del archivo se instala como la nueva configuración crontab.

El editor por defecto es /bin/vi , sin embargo,crontab, al igual que otros comandos, examina la variable de entorno EDITOR. Si la variable se ha establecido, se utilizará para especificar el editor que se va a abrir. Por ejemplo, si hogan prefiere utilizar el editor nano, primero puede configurar la variable de entorno EDITOR como /usr/bin/nano (o simplemente nano) y luego ejecutar crontab -e.

Si hogan quisiera utilizar nano como su editor podría utilizar uno de los siguientes métodos:

[hogan@station hogan]$ export EDITOR=nano [hogan@station hogan]$ crontab -e

o

Managing Processes

55

[hogan@station hogan]$ EDITOR=nano crontab -e

o aún mejor, hogan pudo agregar la línea "export EDITOR=nano" a su archivo .bash_profile y la variable de entorno se establecería automáticamente cada vez que inicie sesión.

En resumen, hay dos formas de crear o modificar la configuración crontab.

1. Crear un archivo de texto que contenga su configuración deseada y luego instalarlo con crontab FILENAME .

2. Editar su configuración establecida con crontab -e.

¿A dónde va la salida?

¿Cómo recibe el usuario la salida de los comandos que cron ejecuta? El demonio enviará por correo la stdout y el stderr de todos los comandos ejecutados al usuario local. Suponga que ventura configuró el siguiente trabajo cron:

05 * * * * cal

Una vez por hora, a la hora y cinco minutos espera recibir un nuevo correo como el siguiente:

Date: Wed, 18 Jun 2003 14:24:00 -0400 From: [email protected] (Cron Daemon) To: [email protected] Subject: Cron <ventura@station> cal X-Cron-Env: <SHELL=/bin/sh> X-Cron-Env: <HOME=/home/ventura> X-Cron-Env: <PATH=/usr/bin:/bin> X-Cron-Env: <LOGNAME=ventura> June 2003 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

El mensaje del correo contiene la salida del comando en el cuerpo y todas las variables de entorno en los encabezados.

Opcionalmente, ventura podría haber definido la variable de entorno especial MAILTO a una dirección de correo electrónico y el correo sería enviado a esa dirección en su lugar:

[email protected] 05 * * * * cal

Managing Processes

56

Variables de entorno y cron

Al configurar trabajos cron, los usuarios deberían tener en cuenta un detalle. Cuando el demonio crond inicia el comando del usuario, éste no ejecuta el comando desde la shell sino que bifurca y exec el comando directamente. Esto tiene una implicación importante: cualquier variable de entorno o alias configurados por la shell en el arranque tal como cualquiera que esté definida en /etc/profile o ~/.bash_profile , no estarán disponibles cuando cron ejecute el comando.

Si un usuario quiere que una variable de entorno esté definida necesita explícitamente definir la variable en su configuración crontab.

Ejemplos

Control de un sitio web

ventura quiere asegurarse que no se va a perder de ninguna nueva oportunidad de formación de su compañía favorita, Red Hat Inc. Con el fin de estar pendiente de estas oportunidades configura un trabajo cron que descargará la página web de formación de Red Hat y se la enviará como un correo electrónico una vez por la mañana. Con el fin de modificar su configuración en el lugar utiliza el comando crontab -e.

[ventura@station ventura]$ crontab -e no crontab for ventura - using an empty one (... while in the text editor, ventura adds the fol lowing line...) 00 05 * * * links -dump http://www.redhat.com/train ing (... and quits the text editor...) crontab: installing new crontab

Luego confirma que su trabajo cron esté en su lugar.

[ventura@station ventura]$ crontab -l # DO NOT EDIT THIS FILE - edit the master and reins tall. # (/tmp/crontab.10296 installed on Wed Jun 18 14:17 :43 2003) # (Cron version -- $Id: 010_text.dbk,v 1.1 2005/03/ 21 05:24:29 brads Exp $) 00 05 * * * links -dump http://www.redhat.com/train ing

ventura ahora puede esperar recibir correo electŕonico, conteniendo una versión formateada de texto de la página web de formación de Red Hat cada mañana a las 5:00.

Control de archivos grandes

Managing Processes

57

Luego, ventura se da cuenta que ha tenido la mala costumbre de crear archivos muy grandes y luego los olvida. Con el fin de ayudarse a recordar los archivos grandes que está dejando atrás, configura un trabajo cron el cual le enviará cada domingo un correo con una lista de todos los archivos mayores de 100k.

[ventura@station ventura]$ crontab -e no crontab for ventura - using an empty one (... within the text editor, ventura adds the follo wing line...) 05 05 * * 0 find $HOME -size +100k (... and exits the text editor ...) crontab: installing new crontab [ventura@station ventura]$ crontab -l # DO NOT EDIT THIS FILE - edit the master and reins tall. # (/tmp/crontab.10678 installed on Wed Jun 18 14:50 :39 2003) # (Cron version -- $Id: 010_text.dbk,v 1.1 2005/03/ 21 05:24:29 brads Exp $) 00 05 * * * links -dump http://www.redhat.com/train ing 10 05 * * 0 find $HOME -size +100k

Ahora, los domingos a las 5:10 de la mañana, ventura puede esperar recibir un correo electrónico listando todos los archivos mayores de 100 K bajo su directorio de inicio.

Ejecución de scripts desde cron

Continuando con sus esfuerzos de no desperdiciar espacio duro, ventura desearía crear regularmente una lista separada de archivos a los que no haya tenido acceso reciéntemente y recibir esta lista al mismo tiempo que recibe su lista de archivos grandes. En lugar de complicar su archivo cron, crea un guión llamado cron.weekly , lo coloca en el subdirectorio bin y lo hace ejecutable.

[ventura@station ventura]$ cat cron.weekly #!/bin/bash echo "===== files larger than 100k =====" find $HOME -size +100k echo echo "==== files not used in the past month =====" find $HOME -atime +30 [ventura@station ventura]$ mkdir bin [ventura@station ventura]$ mv cron.weekly bin/ [ventura@station ventura]$ chmod 755 bin/cron.weekly

Luego, modifica su configuración crontab para que su guión se ejecute como un trabajo cron una vez por semana:

Managing Processes

58

[ventura@station ventura]$ crontab -e (... within the text editor, ventura edits the foll owing line ...) 05 05 * * 0 find $HOME -size +100k (... so that it reads ...) 05 05 * * 0 bin/cron.weekly (... and exits ...) crontab: installing new crontab [ventura@station ventura]$ crontab -l # DO NOT EDIT THIS FILE - edit the master and reins tall. # (/tmp/crontab.11252 installed on Wed Jun 18 15:45 :53 2003) # (Cron version -- $Id: 010_text.dbk,v 1.1 2005/03/ 21 05:24:29 brads Exp $) 00 05 * * * links -dump http://www.redhat.com/train ing 05 05 * * 0 bin/cron.weekly

Ahora en lugar de mantener su configuración crontab, ventura puede apenas modifica el script cron.weekly .

Impresión de fanmail

El usuario hogan ha llegado al punto donde imprime el archivo que recoge la nueva correspondencia de los admiradores, fanmail.txt , cada lunes, miércoles y viernes. Decide utilizar el servicio cron para automatizar el proceso.

Debido a que esta es la primera vez que utiliza cron, él no tiene que preocuparse por la posibilidad de remplazar trabajos ya existentes. Entonces configura un archivo cron localmente. Mediante un editor de texto, crea el archivo crontab.hogan en su directorio de inicio. Luego instala el archivo con el comando crontab.

[hogan@station hogan]$ cat crontab.hogan 45 13 * * 1,3,5 lpr fanmail.txt [hogan@station hogan]$ crontab crontab.hogan

Ahora espera que su archivo de correspondencia de sus admiradores sea impreso los lunes, miércoles y viernes en las tardes a la 1:45. Cuando se imprimen las primeras copias se envían a la impresora que no es, hogan nota que su .bash_profile configura su variable de entorno PRINTER para cola de espera local, hp-color, automáticamente cuando inicia sesión. Sin embargo, como cron no utiliza una shell para ejecutar trabajos cron, la variable de entorno de inicio sesión no se está configurando. Edita crontab.hogan para definir explícitamente y vuelve a someter el archivo con crontab.

[hogan@station hogan]$ cat crontab.hogan PRINTER=hp-color 45 13 * * 1,3,5 lpr fanmail.txt

Managing Processes

59

[hogan@station hogan]$ crontab crontab.hogan

Ahora su trabajo imprime en la impresora correcta.

Ejercicios en línea

Control de quién está en el sistema.

Ejercicio en línea Objetivo: Configurar un trabajo cron

Estimated Time: 10 mins.

Especificaciones

Está un poco paranóico y quiere controlar quién está usando su computador en la noche. Configura un trabajo cron que le enviará por correo la salida del comando who diariamente a las 4:35 de la mañana.

Deliverables

Question 1

1. Una configuración cron que envía por correo la salida del comando who

diariamente a las 4:30 am.