Gestión de procesos en Linux
1 Obtener información sobre los procesos
1.1 PS
Muestra información sobre los procesos en ejecución. Según las opciones que
le indiquemos muestra más o menos información. Las columnas más
destacadas son:
p o PID: Process ID, número único o de identificación del proceso.
P o PPID: Parent Process ID, padre del proceso
U o UID: User ID, usuario propietario del proceso
t o TT o TTY: Terminal asociada al proceso, si no hay terminal aparece
entonces un ‘?’
T o TIME: Tiempo de uso de cpu acumulado por el proceso
c o CMD: El nombre del programa o comando que inició el proceso
RSS: Resident Size, tamaño de la parte residente en memoria en kilobytes
SZ o SIZE: Tamaño virtual del proceso
NI: Nice, valor nice (prioridad) del proceso, un número positivo significa
menos tiempo de procesador y negativo más tiempo (-20 a 19)
C o PCPU: Porcentaje de cpu utilizado por el proceso
STIME: Starting Time, hora de inicio del proceso
S o STAT: Status del proceso, estos pueden ser los siguientes:
o R runnable, en ejecución, ejecutándose
o S sleeping, proceso en ejecución pero sin actividad o esperando
o T sTopped, proceso parado, pero puede ser reiniciado
o Z zombie, proceso que no terminó de manera correcta (no debe haber
procesos zombies)
o D uninterruptible sleep, generalmente asociados con E/S del sistema
o X dead, muerto, terminado pero que sigue apareciendo (no debe haber)
Una peculiaridad de ps es que acepta opciones en varios formatos: Unix98
(guión seguido de un único carácter), BSD (único carácter sin guión) y GNU
largas (dos guiones y una palabra, no se pueden agrupar)
Destacamos las siguientes:
–e / -A : Muestra todos los procesos de actuales
-f, -l, -F, u: Muestra información extra sobre los procesos.
-H / f: Agrupan los procesos según su jerarquía
-u usuario: muestra solo los procesos de un usuario determinado
Estas opciones se pueden combinar hasta conseguir la información deseada,
para más opciones sobre la información de salida puede utilizar ps --help o
1.2 PSTREE
Si se desea ver únicamente la jerarquía de procesos sin más datos adicionales
usar el comando pstree.
Nota: El paquete que contiene los comandos pstree y killall es psmisc
1.3 TOP
Para comprobar en tiempo real cómo están consumiendo recursos los procesos
del sistema es muy útil el comando top. En primer lugar muestra información
relevante sobre el estado del sistema: su carga, cantidad de procesos según su
estado, uso de la CPU y cómo está siendo utilizada la memoria. Después
muestra en tiempo real información sobre el consumo de recursos de todos los
procesos que se están ejecutando. Por defecto ordenará la lista de procesos
según el uso actual de CPU.
Una vez dentro podemos pulsar la tecla h para recibir ayuda del uso de las
teclas en top, destacamos:
k: pide un PID y destruye el proceso
r: cambia la prioridad de un proceso
s: modifica la velocidad de actualización de los datos
M: hace que la lista de procesos se ordene por consumo de memoria
q: sale de top
Otros programa similar, pero aún más visual y directo es htop, para
monitorizar la entrada/salida y escritura de ficheros existe iotop . Ambos se
tendrán que instalar desde los repositorios
1.4 FREE
Proporciona información sobre el uso de la memoria, tanto principal como
swap. Se puede usar la opción -h.
1.5 UPTIME
Muestra el tiempo que está funcionando el sistema operativo desde el último
reinicio, así como la carga media del mismo en el último minuto, últimos 5
minutos y últimos 15 minutos. Un valor cercano a 1 por núcleo significa que
el sistema está rindiendo sobre sus capacidades, menos es que tiene poca
carga y más significa que los procesos tienen que esperar para ser atendidos.
Un valor “saludable” sería no más de 0.7.
1.6 PGREP
Permite seleccionar los procesos que concuerden con un patrón dado (se
comporta como grep). Además, también puede buscar buscar por atributos
como el usuario, padre del proceso, terminal donde se ejecuta, etc.
Por defecto nos devuelve los PID de los procesos seleccionados, algo que
resulta útil para combinarlos con comandos de gestión de procesos. Si
queremos que muestre también el nombre usaremos la opción -l
Ejemplos:
pgrep -u alumno tar
Muestra los procesos que contienen la cadena ‘tar’ y pertenecen al usuario
alumno
pgrep -l '^a'
Muestra los PID y el nombre de los procesos que empiecen por a (pgrep es
compatible con regex)
Nota: El paquete que contiene los
comandos pgrep, pkill, top y uptime es procps
2 Administrar procesos
2.1 KILL
El comando kill sirve para enviar señales a los procesos. Se les puede ordenar
que pausen su ejecución, que continúen, que terminen o si no responden a las
señales, eliminarlos del sistema (SIGKILL).
La lista de señales se puede consultar con kill -l
Se puede usar el nombre o el número de señal, pero siempre habrá que indicar
el PID (uno o varios) de los procesos a los que se les enviará la señal.
Las señales más comunes son:
9 (KILL): mata el proceso.
15 (TERM): le pide el proceso que termine de forma controlada
19 y 20 (STOP): para el proceso, pero no lo cierra. Lo pone en pausa.
18 (CONT): continua un proceso parado.
Ejemplos:
kill -STOP 5670
Envía la señal de parar el proceso con PID 5670
kill -9 5670
Mata el proceso con PID 5670
2.2 PKILL
Funciona Igual que kill, pero en lugar de utilizar el PID se puede utilizar su
nombre (compatible con patrones) y otros criterios como el nombre de
usuario, etc. Si no se indica la señal (se indica después de un guión), por
defecto usa SIGTERM
Ejemplos:
pkill firefox
pkill -STOP -u root tuxracer
2.3 KILLALL
Funciona de forma similar al comando kill, pero en lugar de necesitar los
identificadores de los procesos a los que mandar la señal, lo hace basándose
en el nombre del proceso. De esta forma podemos mandar la misma señal a
todos los procesos que tengan un nombre igual o similar. Por ejemplo todas
las pestañas de un navegador, o los programas de backups o antivirus que
puedan estar ejecutándose en segundo plano.
Con la opción -i nos pregunta por cada proceso antes de mandarle la señal y
con -r podemos usar expresiones regulares en el nombre del proceso.
Ejemplos:
kill -9 chromium
Mata todos los procesos que se llamen chromium
kill -9 5670
Mata el proceso con PID 5670
3 Procesos en segundo plano
Cuando ejecutamos un comando en el terminal debemos esperar a que termine
para poder seguir utilizando el sistema y enviar el siguiente comando. Para
instrucciones breves no supone un problema, pero para tareas lentas como
copias de seguridad, escaneos o búsquedas implicaría pasar muchísimo tiempo
esperando sin poder utilizar el mismo terminal. Una de las soluciones posibles
es ejecutar comandos en segundo plano, es decir, el proceso está realizando su
tarea, pero el terminal queda libre para seguir ejecutando comandos.
3.1 El carácter &
Si queremos que un comando se ejecute directamente en segundo plano
pondremos al final de la orden el carácter &. Por ejemplo: clamscan /home/
> /var/log/[Link] &
Es importante recordar que si el programa que se va a ejecutar en segundo
plano manda información a la salida estándar (al monitor), lo seguirá
haciendo, por eso suele ser recomendable redirigirla hacia otro lugar para que
no se mezcle con otras salidas.
3.2 JOBS
Cuando enviamos un proceso a que se ejecute en segundo plano se le asocia
un número ID (no confundir con su PID), que será un entero consecutivo
empezando por el 1. Es relativo a la sesión actual, por lo que si tengo varios
terminales abiertos, los números se repetirán en cada uno de ellos (algo que
nunca sucede con los PID).
El comando jobs muestra los procesos que se están ejecutando en segundo
plano, junto con su identificador. Este número se puede utilizar en lugar del
PID para hacer referencia a un proceso. Para que no haya confusión se pone
delante del número el carácter %. Por ejemplo: kill -9 %2
También indica con el carácter + el proceso que se verá afectado si
ejecutamos los comandos fg o bg.
3.3 FG y BG
Si queremos enviar un proceso a segundo plano pero ya se está ejecutando,
podríamos pararlo enviándole una señal, o pulsado CONTROL+Z, después el
comando bg (background) haría que se siguiera ejecutando pero en segundo
plano. Para continuar y volver a tomar el control del terminal,
ejecutaríamos fg (foreground) y el proceso seguiría funcionando en primer
plano.
En el caso que queramos ejecutar estos comandos sobre un proceso concreto
de la lista que ofrece el comandos jobs (no sobre el que está marcado con un
+) podríamos enviar como parámetro el número de su identificador, por
ejemplo fg %2
3.4 Nohup
Si ejecutamos una tarea que necesita mucho tiempo y queremos dejarla
funcionando sin dejar el terminal abierto, tenemos el problema de que al
terminar el proceso padre (el terminal) que lanzó la tarea, también se mandan
señales para que terminen todos los procesos hijos. Así que al cerrar el
terminal, nuestro proceso terminará también. Si queremos que esto no suceda
podemos escribir antes del comando deseado, la orden nohup. Esto hará que
dicho proceso ignore la orden de terminar la ejecución (SIGHUP)
Ejemplo: nohup tar -czf /backups/[Link] /home/
Nota: Para que el sistema envíe el la señal SIGHUP al cerrar sesión tiene que
estar activada la opción huponexit => shopt -s huponexit
3.4 Señales
Como hemos indicado, en ocasiones queremos terminar algún proceso, por ejemplo porque
deja de responder o tarda demasiado en completarse; para hacerlo puede emplear el
programa kill para enviarle una señal de terminación. Una señal es como una "llamada de
atención" que se hace a un proceso en situaciones excepcionales (por ejemplo errores),
pueden ser producidas por otros procesos, por el usuario o por el sistema operativo y en la
mayoría de los casos conducen a la terminación del proceso que recibe la señal. Hay diversos
tipos de señales, cada una tiene un número, un nombre que la identifica y una acción
predefinida (que generalmente puede ser cambiada por el proceso). Un usuario puede enviar
una señal a un proceso con el programa kill seguido de la señal que enviará y del proceso que
la recibirá:
kill -SIGTERM 945
Este ejemplo envía la señal SIGTERM al proceso con identificación 945 (en vez de SIGTERM
pudo haberse usado 15 que es el número que corresponde a esa señal). Puede consultar un
listado de todas las señales y sus números con kill -l.
A continuación se presenta una breve descripción de algunas señales comúnmente empleadas
por usuarios:
15 SIGTERM
Esta señal solicita la terminación del proceso que la recibe.
9 SIGKILL
Esta señal termina el proceso que la recibe de forma inmediata. Empleela sólo para detener
procesos que no terminan con la señal SIGTERM.
2 SIGINT
Es la misma señal que se produce cuando un usuario en un programa interactivo presiona,
Control-C para solicitar su terminación.
3 SIGQUIT
La misma señal producida por Control-\, su efecto es análogo al de SIGINT pero además actúa
como si el programa hubiera provocado algún error interno (volcando el contenido de
memoria a un archivo core).
20 SIGTSTP
La misma señal producida por Control-z, su efecto es suspender la ejecución de un proceso ---
para reanudarla después.
18 SIGCONT
Reanuda un proceso suspendido previamente por la señal SIGTSTP.
1 SIGHUP
Esta señal es enviada por bash a todas las tareas que se ejecutan en segundo plano, cuando el
usuario cierra la sesión (por ejemplo al cerrar una terminal en X-Window o cuando sale de su
sesión desde una consola virtual). Normalmente un proceso terminará cuando reciba esta
señal, pero puede lograrse que el proceso continué (es decir que ignore la señal SIGHUP) si el
comando se inició con nohup ---que evita que el programa reciba la señal SIGHUP) o si durante
su ejecución se indicó a bash no enviarle esta señal cuando se cierre la sesión, empleando el
comando disown. Esto es muy útil cuando debe dejar corriendo un proceso muy demorado
(horas o días) mientras usted no tiene una sesión abierta, por ejemplo para ejecutar el
programa make [41] en segundo plano, redireccionado salida estándar al archivo sm, error
estándar a esm y lograr que continue después de que se cierre la sesión:
nohup make > sm 2> esm &
PRÁCTICA
1. Inicia Ubuntu. Desde la línea de mandatos. Ejecuta ps y visualiza los procesos
que se están ejecutando en este momento. El primer valor que aparece es el
identificador de proceso (PID). El segundo es la terminal que está asociada a
ese proceso. Después también podemos observar el tiempo acumulado de uso
de CPU, y finalmente el nombre del programa que ha dado lugar a este
proceso. Apunta los procesos activos y sus valores.
2. Por defecto, ps sólo ha mostrado los procesos asociados con la misma terminal
e iniciados por el mismo usuario. Vamos a recuperar las opciones que nos
permiten mostrar todos los procesos. Ejecuta el mandato ps –e. Comprueba la
lista de procesos que están corriendo en tu máquina. ¿Cuál lleva el PID igual a
1? ¿Qué procesos se están ejecutando en las terminales tty1, tty2...tty6?
3. El comando ps todavía nos puede ofrecer más información sobre los procesos
en ejecución. Por ejemplo, ¿quién ha iniciado cada uno de los procesos en
nuestra máquina? Vamos a usar las siguientes opciones del mandato ps:
“a” nos permite conocer todos los procesos que tienen una terminal asociada;
“x” aquellos que no tienen terminal;
La opción “u” nos muestra la salida en un formato más legible.
Teclea el mandato ps aux. Observa en las cabeceras la información que has
obtenido de cada proceso. Busca en [Link]
el significado de aquellas columnas que desconozcas y apúntalo en tu informe
(por ejemplo, RSS, 2 - 8 VSZ). Busca también en el anterior enlace y apunta en
tu informe, en la sección “PROCESS STATE CODES”, el significado del status de
cada uno de los procesos que están en ejecución.
4. Todos los comandos y opciones que hemos visto hasta ahora ofrecían
información estática sobre los procesos. Esta información se extrae del
directorio “/proc” del sistema. Hay algunas aplicaciones que también nos
permiten conocer en tiempo real las características de cada proceso (CPU,
RAM que están consumiendo). Ejecuta el mandato man top. ¿Qué hace el
mandato top?
Como puedes observar, la información sobre el sistema se refresca cada 3
segundos (se puede modificar ese parámetro). Por lo demás, la interfaz de
usuario de top no es especialmente agradable, aunque sí resulta sencillo
modificar ciertas opciones y ajustarla a nuestros requisitos. Pulsa “q” para salir
de top. Hace unos días nos descargamos la aplicación “htop”. Si no la tienes
vuélvela a descargar y ejecútala. Compárala con top e indica las principales
diferencias que veas.
5. Ejecuta ahora el mandato “top –u usuario”. ¿Cómo ha cambiado la salida del
mandato? ¿A quién pertenecen los procesos que observas ahora?
6. Veamos ahora algunos atajos de teclado que nos permiten gestionar procesos.
Comprueba la función del mandato yes. Aunque el mismo pueda no parecer de
gran utilidad a nosotros nos va a servir para comprobar cómo podemos
detener y “matar” procesos. Ejecuta el mandato “yes hola”. Observa que el
mensaje aparece infinitas veces.
Vamos a “matar” esa tarea. Intenta salir de la tarea con “q”. La tecla “q” nos
permite salir de ciertas aplicaciones en ejecución, pero no acabar con una
tarea. Teclea el atajo “Ctrl + C”. El mismo debería terminar con el proceso
activo. ¿Qué ha sucedido? El atajo de teclado “Ctrl + C” se encarga de terminar
(o matar) una tarea. El atajo “Ctrl + Z” se encarga únicamente de detenerla
(aunque el proceso siga “vivo” y se pueda retomar en el estado en que se
detuvo). Finalmente, el atajo “Ctrl + Y” suspende un proceso hasta que el
mismo disponga de una nueva entrada.
7. Podemos ahora redirigir la salida del mandato a un fichero (observa que esto
podría darnos serios problemas de memoria en nuestra máquina). Para poder
redirigir la salida de mandatos a un fichero sin peligro de que eso colapse
nuestra memoria, Linux dispone de un fichero cuya localización es /dev/null.
Comprueba las propiedades de “/dev/null”.(ls –la). Apunta el tipo de fichero
que es (c), sus permisos, propietario y tamaño. ¿Podemos escribir al mismo?
¿Podemos leer su contenido? Ejecuta el mandato “yes adios > /dev/null”.
Como puedes observar, la tarea en ejecución no permite seguir utilizando la
terminal. Teclea “Ctrl + C” para detenerlo. ¿Qué tamaño ocupa ahora en disco
el fichero /dev/null? ¿Dónde ha ido a parar toda la información que hemos
enviado?
8. Ejecutamos de nuevo el mandato “yes que tal > /dev/null”.
Abre una nueva terminal si cerrar la anterior y localiza el PID del proceso “yes”
iniciado. Puedes usar ps o top. Ahora vamos a comprobar la utilidad del
mandato kill. Como puedes observar, kill nos permite mandar señales a un
proceso. Interrumpe el proceso activo “yes” por medio del mandato kill
ejecuntando (kill –s 15 PID). ¿Qué indica el –s 15?.
En nuestra terminal original vuelve a ejecutar el proceso “yes que tal >
/dev/null” y, desde la segunda terminal que hemos abierto, envíale ahora una
señal de SIGKILL haciendo uso del kill. Comprueba que el resultado externo ha
sido el mismo que antes.
9. No todos los procesos que ejecutamos en una terminal deben ejecutarse en
primer plano (bloqueando así la terminal). También podemos hacer lo que se
conoce como ejecución en segundo plano. Puedes leer en
[Link] información acerca de
las principales diferencias entre ejecutar un proceso en primero o segundo
plano (esencialmente tiene que ver con la prioridad del mismo). La forma de
hacer que un programa se ejecute en segundo plano es escribiendo el
programa en el intérprete de mandatos seguido de un símbolo &; comprueba,
en nuestra terminal original, el siguiente mandato: yes otra vez > /dev/null &
10. Vamos a hacer ahora uso del mandato jobs. Comprueba en primer lugar su
función por medio de “help jobs”, y el significado de la opción “-l”. La
diferencia entre un “job” y un “process” es que los “jobs” son
obligatoriamente iniciados desde una terminal y están asociados a ella (son
procesos “hijos” de la terminal). Ejecuta el mandato “jobs” en la misma
terminal que has ejecutado “yes”. ¿En qué estado se encuentra el proceso?
Compruébalo con los mandatos ps y top. Observa el porcentaje de CPU que
consume. Finaliza el proceso del yes.
11. Entre los procesos de Linux siempre existe una jerarquía definida, ya que cada
proceso debe tener un proceso padre (excepto el proceso de inicio o init). Esta
jerarquía adquiere relevancia ya que “matar” a un proceso padre por lo
general conlleva acabar también con los procesos hijos. En algunos casos, un
proceso padre y sus hijos pueden incluso compartir memoria. Comprueba la
jerarquía de procesos en tu máquina por medio del mandato pstree (puedes
ver alguna de sus opciones en man pstree). Vuelve a ejecutar yes en la misma
terminal y también en segundo plano (yes mensaje > /dev/null &). Comprueba
el árbol de procesos por medio de “pstree -h”. Usando top, anota el porcentaje
de CPU (aproximado) que suman estos dos procesos yes.
Vuelve a comprobar el estado de los procesos iniciados en esta shell por medio
de “jobs”. Comprueba que aparecen las dos tareas iniciadas y que en la
segunda aparece el símbolo + indicando que es la última que se ha ejecutado.
Apunta el estado de ambas.
12. El hecho de que las tareas estén ejecutándose en segundo plano, impide que
les podamos enviar una señal de teclado (por ejemplo, Ctrl + Z, Ctrl + C). A
través de “jobs”, cada tarea que se está ejecutando desde nuestra terminal
recibe un nuevo número (1, 2...). Esos números pueden ser usados con fg
(foreground) para traer dichas tareas a primer plano (fg 1, fg 2), o para
mandarlas a segundo plano (bg 1, bg 2...).
Mata la segunda tarea iniciada (la de mayor PID). Por ejemplo, puedes ejecutar
top y capturar su PID, y enviarle una señal de kill.
Comprueba por medio de jobs que sólo queda una tarea activa.
13. Ejecuta el mandato “yes mensaje2 > /dev/null”. Por medio del teclado (Ctrl +
Z), o por medio de kill (con la señal SIGSTOP ó 19 y con el PID correspondiente)
envía al proceso una señal de “detenido”.
Comprueba que el proceso está detenido por medio de jobs.
Para recuperar una tarea detenida sólo tienes que ejecutar fg (foreground) o
bg (background) y su número de job, dependiendo de que quieras que la tarea
se ejecute en primer o segundo plano. Comprueba con fg que la tarea vuelve a
primer plano.
Por medio de una señal o del atajo de teclado detén de nuevo la tarea. Vuelve
a iniciarla, esta vez en segundo plano (bg). Vuelve a detenerla sin traerla a
primer plano (puedes usar “jobs” para conocer el estado de las tareas en
ejecución). Para ello debes usar obligatoriamente señales por medio de kill.
Crea nuevas tareas por medio de “yes” en primer y segundo plano y prueba a
detenerlas y reanudarlas por medio de bg, fg y las señales de kill.
14. Vamos a recuperar ahora la idea de que todos los procesos dependen de su
proceso “padre”. Ejecuta varias veces seguidas el mandato “yes hola >
/dev/null &”. Ejecuta una nueva terminal. En esta terminal comprueba ahora la
estructura de “pstree”. ¿Quién es el antecesor directo de todos ellos?
Ejecuta “top –u usuario” para comprobar qué tareas tienes en ejecución y
cuáles son las que más recursos consumen. Si cerrases la terminal en que se
encuentran los procesos “yes” ejecutándose, esto “mataría” todos los
procesos “yes” que dependen de la misma. Teniendo en cuenta que “init” es el
proceso “padre” de todos los procesos que están en ejecución, imagina lo que
sucedería al ejecutar “kill –s 9 1”. Desde la consola original, envía una señal de
terminación a todos los procesos “yes” creados (trayéndolos a “fg” y
ejecutando “Ctrl + C” o enviándoles una señal a través de “kill”).