← Terminal y Línea de Comandos en Linux Bloque 7 · Procesos y entorno · Tema 32 de 43

Tema 32

Ver los procesos: ps, top y htop

La terminal está quieta, con el cursor esperando. Da la impresión de que la computadora no hace nada. En ese mismo instante hay cerca de trescientos programas en marcha: el que dibuja las ventanas, el que atiende la red, el que lleva la hora, tu propia shell. Hasta ahora trabajamos con lo que está guardado, los archivos. Este bloque se ocupa de lo que está ocurriendo. Y lo primero es aprender a mirar: qué se está ejecutando, de quién es, cuánto consume y cómo encontrar, entre cientos, el proceso que interesa.

1. Programa y proceso

Las dos palabras se usan como sinónimos, y no lo son. La diferencia es la que hay entre una receta y el acto de cocinar.

Un programa es un archivo guardado en el disco, con instrucciones. Un proceso es un programa en ejecución: el kernel lo cargó en memoria, le asignó recursos y lo está haciendo avanzar.

ProgramaProceso
EsUn archivo: /usr/bin/bashUna actividad del sistema
Está enEl discoLa memoria
DuraHasta que se lo borreDesde que se lo lanza hasta que termina
Cuántos hayUnoLos que se hayan lanzado: cero, uno o veinte
Se ve conls, file, whichps, top, htop

La cuarta fila es la que mejor muestra la diferencia. Hay un solo archivo /usr/bin/bash; si abres tres terminales hay tres procesos bash, cada uno con su directorio actual, su historial y sus variables, sin que ninguno sepa de los otros.

Cada comando que ejecutaste en este curso fue un proceso. La mayoría vivió una fracción de segundo: ls nació, escribió su lista y terminó. Otros duran lo que dura la sesión, como la shell, o lo que dura el encendido, como los servicios que trabajan sin ventana ni terminal, y que por tradición se llaman demonios. Repartir el procesador y la memoria entre todos ellos, de modo que parezcan funcionar a la vez, es la tarea central del kernel.

Para tener algo concreto que observar, abre una segunda terminal y ejecuta en ella un comando que no hace nada durante una hora:

en la segunda terminal
$ sleep 3600
█

sleep espera la cantidad de segundos indicada y termina. Mientras tanto esa terminal queda ocupada, sin indicador: hay un proceso en marcha. Déjala así y vuelve a la primera; al terminar el tema lo detendremos con Ctrl+C.

2. Lo que el kernel anota de cada proceso

El kernel lleva una ficha de cada proceso. Todo lo que muestran las herramientas del tema son datos de esa ficha, y conviene conocer los principales antes de verlos en columnas:

DatoQué es
PIDEl identificador del proceso (process ID): un número único mientras el proceso vive. Es su nombre propio para el sistema.
PPIDEl PID de su padre: el proceso que lo lanzó.
DueñoEl usuario con cuya identidad se ejecuta, y que decide qué archivos puede tocar, como vimos en el tema 16.
EstadoSi está usando el procesador, esperando algo o detenido.
TerminalLa terminal a la que está conectado, si tiene alguna.
ConsumoCuánto tiempo de procesador lleva usado, y cuánta memoria ocupa.
Línea de comandosEl comando y los argumentos con que se lo lanzó.

El PID es el dato central: todo lo que se le hace a un proceso —consultarlo, pausarlo, terminarlo— se hace nombrándolo por ese número. Los PID se asignan en orden creciente, a medida que nacen los procesos, y al llegar al máximo se vuelve a empezar reutilizando los que quedaron libres.

La shell conoce su propio PID, y lo guarda en una variable especial:

terminal
$ echo $$
3187

El número será otro en tu sistema, y cambia cada vez que abres una terminal. En los ejemplos del tema la shell es siempre la 3187, la misma que apareció en los temas 16 y 27.

3. ps: una foto

El comando básico es ps, de process status. Sin opciones es muy discreto:

terminal
$ ps
    PID TTY          TIME CMD
   3187 pts/0    00:00:00 bash
   7412 pts/0    00:00:00 ps
ColumnaContiene
PIDEl identificador del proceso.
TTYLa terminal a la que está conectado. pts/0 es la primera ventana de terminal abierta.
TIMEEl tiempo de procesador que lleva consumido. No es el tiempo que lleva abierto.
CMDEl nombre del comando.

De los cientos de procesos del sistema mostró dos: sin opciones, ps se limita a los tuyos que estén conectados a esta terminal. Uno es la shell. El otro es el propio ps, que para hacer la lista tuvo que estar en ejecución, y se incluyó. El sleep de la otra ventana no figura: es tuyo, pero pertenece a otra terminal.

La shell lleva horas abierta y su TIME es cero. No hay error: pasó casi todo ese tiempo esperando que escribieras, y esperar no consume procesador.

ps saca una foto, no filma

ps mira la tabla de procesos una vez, escribe lo que encontró y termina. Su salida es el estado del sistema en ese instante: un segundo después puede haber procesos nuevos y faltar algunos de los listados. La prueba es el propio ps, que figura en la lista y ya no existe cuando se la lee. Por ser texto que no cambia, esa foto se puede filtrar, ordenar y guardar con todo lo aprendido en el bloque anterior. Para ver el sistema en movimiento está top, en la sección 10.

4. Todos los procesos: ps aux y ps -ef

Para ver más hay que pedirlo, y aquí aparece una rareza que anunciamos en el tema 3. ps es uno de los comandos más antiguos de Unix, y heredó las costumbres de las distintas familias del sistema. Acepta tres estilos de opciones:

EstiloSe escribeEjemplo
UNIXCon un guion.ps -ef
BSDSin guion.ps aux
GNUCon dos guiones y una palabra.ps --forest

La consecuencia práctica es que hay dos fórmulas para «todos los procesos del sistema, con detalle», una de cada tradición. Las dos se usan, las dos aparecen en la documentación, y alcanza con memorizarlas como si fueran palabras:

terminal
$ ps aux | head -n 4
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.1 168572 13184 ?        Ss   09:02   0:02 /sbin/init splash
root           2  0.0  0.0      0     0 ?        S    09:02   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   09:02   0:00 [rcu_gp]
$ ps -ef | head -n 4
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 09:02 ?        00:00:02 /sbin/init splash
root           2       0  0 09:02 ?        00:00:00 [kthreadd]
root           3       2  0 09:02 ?        00:00:00 [rcu_gp]
$ ps aux | wc -l
288
ps auxps -ef
Las letrasa: de todos los usuarios; u: con formato orientado al usuario; x: también los que no tienen terminal.-e: todos (every); -f: formato completo (full).
Lo que solo esta muestraEl consumo: %CPU, %MEM, la memoria y el estado.El PPID: quién es el padre.
Conviene paraSaber qué está consumiendo recursos.Saber quién lanzó a quién.

La lista tiene casi trescientas líneas —287 procesos y el encabezado—, de modo que casi nunca se la lee entera: se la pasa a less para recorrerla, o a grep para buscar en ella.

ps aux y ps -aux no son lo mismo

Por costumbre de otros comandos, es fácil escribir ps -aux, con guion. En el estilo UNIX eso significa otra cosa: «todos los procesos, y además los del usuario llamado x». Como normalmente no existe un usuario x, ps adivina la intención y responde como ps aux, a veces con una advertencia. Funciona por cortesía, no por derecho. Lo correcto es ps aux sin guion, o ps -ef con guion.

5. Leer las columnas de ps aux

Tomamos de la lista completa unas pocas líneas representativas, las de la sesión de ana:

fragmento de la salida de ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.1 168572 13184 ?        Ss   09:02   0:02 /sbin/init splash
root           2  0.0  0.0      0     0 ?        S    09:02   0:00 [kthreadd]
root         812  0.0  0.1 245128  9216 ?        Ssl  09:02   0:01 /usr/sbin/NetworkManager --no-daemon
ana         2954  1.2  4.8 4712340 389120 ?      Ssl  09:03   9:14 /usr/bin/gnome-shell
ana         3170  0.3  0.7 562204 58112 ?        Ssl  19:02   0:27 /usr/libexec/gnome-terminal-server
ana         3187  0.0  0.0  11212  5376 pts/0    Ss   19:02   0:00 bash
ana         6950  0.0  0.0  11212  5248 pts/1    Ss   21:28   0:00 bash
ana         7398  0.0  0.0   8284  1920 pts/1    S+   21:29   0:00 sleep 3600
ana         7431  0.0  0.0  12676  3456 pts/0    R+   21:30   0:00 ps aux
ColumnaContiene
USEREl dueño del proceso.
PIDSu identificador.
%CPUEl porcentaje de procesador que usó, en promedio desde que nació.
%MEMEl porcentaje de la memoria física que ocupa.
VSZLa memoria virtual, en kilobytes: todo lo que el proceso tiene reservado, lo use o no.
RSSLa memoria residente, en kilobytes: lo que ocupa de verdad en la memoria física en este momento.
TTYSu terminal. Un signo ? indica que no tiene ninguna.
STATEl estado, en letras. Sección 6.
STARTLa hora en que se inició; la fecha, si fue otro día.
TIMEEl tiempo de procesador acumulado.
COMMANDLa línea de comandos completa, con sus argumentos.

Ahora se puede leer el fragmento como un relato. El sistema arrancó a las 09:02, y el primer proceso, el de PID 1, es de root. Un minuto después ana inició sesión y arrancó el escritorio, gnome-shell, que es el que más memoria ocupa de la lista: 389 MB, el 4,8 % del total. A las 19:02 abrió una terminal, y con ella nació la shell 3187. A las 21:28 abrió la segunda, donde corre el sleep. La última línea, otra vez, es el ps mirándose a sí mismo.

Cuatro observaciones sobre los detalles que más confunden:

Se veSignifica
Un ? en TTYUn proceso sin terminal: un servicio del sistema o un programa gráfico. Son la gran mayoría.
Un nombre entre corchetes, como [kthreadd]Un hilo del kernel: no es un programa del disco, sino una tarea interna del propio kernel. Por eso su memoria figura en cero. No se tocan.
VSZ mucho mayor que RSSEs lo normal. La memoria reservada no es memoria usada. Para saber cuánto ocupa un proceso se mira RSS.
TIME de 9:14 en un proceso que lleva doce horasEn doce horas usó nueve minutos de procesador. El resto del tiempo estuvo esperando.

El %CPU de ps merece una advertencia aparte. Es un promedio de toda la vida del proceso: tiempo de procesador usado, dividido por el tiempo transcurrido desde que nació. Un programa que estuvo tranquilo diez horas y se desbocó hace un minuto mostrará un valor bajo. Para saber qué está consumiendo procesador ahora, la herramienta es top.

6. Los estados de un proceso

En la lista anterior casi todos los procesos tienen una S en la columna STAT, y solo uno una R. Es lo esperable, y explica por qué una computadora con trescientos procesos puede estar desocupada.

El estado de un proceso indica qué está haciendo respecto del procesador: usándolo, esperando un acontecimiento, o detenido.

LetraEstadoQué significa
RRunning, en ejecuciónEstá usando el procesador, o listo para usarlo en cuanto le toque el turno.
SSleeping, durmiendoEspera algo: una tecla, un dato de la red, que pase un tiempo. No consume procesador.
IIdle, ociosoUn hilo del kernel sin trabajo.
DEspera no interrumpibleEspera una operación del disco u otro dispositivo, y no puede ser interrumpido hasta que termine.
TStopped, detenidoAlguien lo puso en pausa, por ejemplo con Ctrl+Z. Tema 33.
ZZombieYa terminó, pero su padre todavía no recogió su resultado.

La shell está en S: duerme hasta que pulses una tecla. El sleep duerme hasta que pase una hora. El único en R es ps, que en ese instante estaba trabajando. En un sistema en reposo, casi todo duerme casi todo el tiempo.

Después de la letra principal pueden venir otros caracteres, que agregan detalles:

CarácterSignifica
sEs líder de sesión: típicamente, la shell de una terminal.
+Está en primer plano en su terminal: es el que recibe lo que se teclea.
lTiene varios hilos de ejecución.
<Tiene prioridad alta.
NTiene prioridad baja: cede el paso a los demás.

Así, Ss en la línea de bash se lee «durmiendo, y líder de su sesión», y S+ en la de sleep, «durmiendo, en primer plano». En la terminal pts/1 la shell está detrás, esperando a que el sleep termine.

El estado zombie tiene un nombre que alarma más de lo que debe. Cuando un proceso termina, el kernel conserva su ficha hasta que el padre pregunte cómo le fue; en ese intervalo, el proceso figura como Z, o <defunct>. No ocupa memoria ni procesador: es solo un renglón en la tabla, y normalmente dura un instante. Uno o dos que permanecen no hacen daño; cientos indican un programa mal escrito, el padre, que no cumple con su parte.

7. Elegir columnas, filtrar y ordenar

ps aux y ps -ef son dos formatos armados de antemano. Con la opción -o se arma uno a medida, nombrando las columnas que se quieren y en qué orden:

terminal
$ ps -o pid,ppid,stat,etime,cmd
    PID    PPID STAT     ELAPSED CMD
   3187    3170 Ss      02:31:12 bash
   7440    3187 R+         00:00 ps -o pid,ppid,stat,etime,cmd
NombreColumna
pid, ppidEl identificador del proceso; el de su padre.
userEl dueño.
%cpu, %memLos porcentajes de procesador y de memoria.
rss, vszLa memoria residente y la virtual, en kilobytes.
statEl estado.
ttyLa terminal.
lstartLa fecha y la hora exactas de inicio.
etimeEl tiempo transcurrido desde que se inició: el que marca el reloj.
timeEl tiempo de procesador consumido.
niEl valor de cortesía, nice, que ajusta la prioridad.
commSolo el nombre del programa, hasta 15 caracteres.
cmd o argsLa línea de comandos completa.

Aquí están, lado a lado, los dos tiempos que conviene no confundir: la shell lleva dos horas y media abierta (etime) y cero segundos de procesador (time). Un nombre de columna seguido de un signo igual, como pid=, suprime su título; con todas así, la salida no tiene encabezado y queda lista para una tubería.

El segundo ajuste es qué procesos se listan. -o se combina con cualquiera de estos selectores:

OpciónSeleccionaEjemplo
-eTodos los procesos.ps -e
-u usuarioLos de un usuario.ps -u ana
-p PIDUno o varios procesos, por su número.ps -p 3187,6950
-C nombreLos que ejecutan ese programa.ps -C bash
-t terminalLos conectados a una terminal.ps -t pts/1

Y el tercero es el orden. Por defecto la lista va por PID, que equivale a ir del proceso más antiguo al más reciente. --sort la ordena por cualquier columna, y un signo menos delante invierte el orden, de mayor a menor. Reuniendo los tres ajustes sale la consulta más útil del tema:

terminal: los procesos que más memoria ocupan
$ ps -eo pid,ppid,user,%mem,rss,comm --sort=-%mem | head -n 5
    PID    PPID USER     %MEM   RSS COMMAND
   5120    2954 ana       9.7 778240 firefox
   2954    2731 ana       4.8 389120 gnome-shell
   5388    5120 ana       3.9 316416 Isolated Web Co
   3170    2731 ana       0.7 58112 gnome-terminal-

El navegador, con casi 780 MB, y dos de sus procesos auxiliares encabezan la lista, como en casi cualquier computadora de escritorio. Los nombres cortados a 15 caracteres son los de la columna comm; con cmd en su lugar se vería la línea de comandos entera.

Como la salida es texto en columnas separadas por espacios, también vale todo lo del bloque anterior. La memoria total que ocupan los procesos de un usuario, en megabytes, es una suma de awk:

terminal
$ ps -u ana -o rss= | awk '{s += $1} END {printf "%.0f MB\n", s / 1024}'
2874 MB
$ ps -eo user= | sort | uniq -c | sort -rn | head -n 3     # cuántos procesos tiene cada usuario
    181 root
     96 ana
      3 systemd+

8. El árbol de procesos

Ningún proceso aparece de la nada: a cada uno lo lanza otro. La shell lanza los comandos que escribes; a la shell la lanzó el programa de terminal; a este, el gestor de tu sesión. Siguiendo la cadena hacia atrás se llega siempre al mismo lugar.

Todo proceso tiene un padre, cuyo identificador es su PPID. El conjunto forma un árbol cuya raíz es el proceso de PID 1, el primero que el kernel pone en marcha al arrancar: en las distribuciones actuales, systemd.

terminal: la cadena de padres de la shell
$ ps -o pid,ppid,cmd
    PID    PPID CMD
   3187    3170 bash
   7452    3187 ps -o pid,ppid,cmd
$ pstree -ps $$
systemd(1)───systemd(2731)───gnome-terminal-(3170)───bash(3187)───pstree(7461)

El primer comando muestra un eslabón: el padre de ps es 3187, la shell, y el padre de la shell es 3170. pstree dibuja la cadena completa. La opción -p agrega los PID, y -s seguida de un PID muestra sus antepasados; $$ es, como vimos, el de la shell.

Árbol de procesos de la sesión: systemd, con PID 1, es padre de systemd de usuario, con PID 2731; este es padre del programa de terminal, con PID 3170; el programa de terminal es padre de dos shells bash, con PID 3187 y 6950; la primera shell es padre de ps y la segunda es padre de sleep systemd · PID 1 systemd --user · 2731 gnome-terminal · 3170 bash · 3187 bash · 6950 ps · 7452 sleep 3600 · 7398 terminal pts/0 terminal pts/1
La rama del árbol que corresponde a las dos terminales abiertas. El PPID de cada proceso es el PID del que tiene encima.

Sin argumentos, pstree muestra el árbol entero del sistema, que conviene pasar a less. ps tiene su propia versión, que agrega el dibujo a la lista habitual:

fragmento de la salida de ps -ef --forest
UID          PID    PPID  C STIME TTY          TIME CMD
ana         3170    2731  0 19:02 ?        00:00:27 /usr/libexec/gnome-terminal-server
ana         3187    3170  0 19:02 pts/0    00:00:00  \_ bash
ana         7470    3187  0 21:33 pts/0    00:00:00  |   \_ ps -ef --forest
ana         6950    3170  0 21:28 pts/1    00:00:00  \_ bash
ana         7398    6950  0 21:29 pts/1    00:00:00      \_ sleep 3600

La relación de padre e hijo no es un dato decorativo. El hijo hereda del padre su dueño, su directorio actual, sus variables de entorno y sus tres canales estándar: por eso un comando escribe en la misma terminal que la shell que lo lanzó. Y explica una pregunta frecuente: qué pasa con los hijos si el padre termina. Quedan huérfanos, y los adopta un proceso superior, en última instancia systemd. Lo veremos en el tema 33, al cerrar una terminal con un programa en marcha.

9. Encontrar un proceso: pgrep

La tarea más frecuente con los procesos es encontrar uno: saber si un programa está en ejecución y cuál es su PID. La forma que todos improvisan es ps aux | grep nombre, y en el tema 27 vimos su defecto: grep se encuentra también a sí mismo, porque su línea de comandos contiene la palabra buscada. La herramienta hecha para esto no tiene ese problema.

pgrep busca procesos por su nombre, con una expresión regular, y escribe sus PID.

terminal
$ pgrep bash
3187
6950
$ pgrep -l sleep                     # con el nombre
7398 sleep
$ pgrep -a sleep                     # con la línea de comandos entera
7398 sleep 3600
$ pgrep firefoxx; echo $?            # no hay ninguno: sin salida, y código 1
1
OpciónEfecto
NingunaEscribe los PID de los procesos cuyo nombre coincide.
-lAgrega el nombre del proceso.
-aAgrega la línea de comandos completa.
-u usuarioSolo los de ese usuario.
-xEl nombre debe coincidir entero, no en una parte.
-fBusca en toda la línea de comandos, no solo en el nombre.
-cCuenta en lugar de listar.
-n, -oSolo el más nuevo; solo el más antiguo.

Dos comportamientos explican casi todas las sorpresas con pgrep. El patrón coincide con una parte del nombre: pgrep sh encuentra bash, sshd y cualquier otro que contenga «sh»; para evitarlo está -x. Y se compara solo con el nombre del programa, no con sus argumentos: un script lanzado como python3 respaldo.py se llama python3, y pgrep respaldo no lo encuentra. Para buscar en la línea entera está -f.

Como la salida de pgrep son números limpios, sirve de entrada a otros comandos mediante la sustitución del tema 25. Así se obtiene la ficha completa de los procesos encontrados:

terminal
$ ps -fp $(pgrep sleep)
UID          PID    PPID  C STIME TTY          TIME CMD
ana         7398    6950  0 21:29 pts/1    00:00:00 sleep 3600
$ pgrep -c -u ana                    # cuántos procesos tiene ana
96
$ pidof bash                         # los PID de un programa, por su nombre exacto
6950 3187

El código de salida de pgrep —cero si encontró algo, uno si no— lo vuelve útil en una condición: pgrep -x firefox > /dev/null && echo "Firefox está abierto". Tiene un comando hermano, pkill, que acepta las mismas opciones y en lugar de listar los procesos les envía una señal; es parte del tema siguiente.

10. top: la película

Para las preguntas sobre el presente —qué está usando el procesador ahora, por qué la máquina está lenta— una foto no alcanza. Hace falta ver cómo cambian las cifras.

top muestra en pantalla completa un resumen del sistema y la lista de procesos, ordenada por consumo de procesador, y la actualiza cada pocos segundos.

terminal: la pantalla de top
$ top
top - 21:34:12 up 12:32,  1 user,  load average: 0.42, 0.35, 0.30
Tasks: 287 total,   1 running, 286 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3.1 us,  1.0 sy,  0.0 ni, 95.6 id,  0.2 wa,  0.0 hi,  0.1 si,  0.0 st
MiB Mem :   7836.4 total,   1210.7 free,   3402.1 used,   3223.6 buff/cache
MiB Swap:   2048.0 total,   2048.0 free,      0.0 used.   4101.9 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   5120 ana       20   0 3412560 778240 201344 S   6.3   9.7  14:02.51 firefox
   2954 ana       20   0 4712340 389120 142208 S   2.0   4.8   9:15.20 gnome-shell
   3170 ana       20   0  562204  58112  43520 S   0.7   0.7   0:27.84 gnome-terminal-
   7480 ana       20   0   13204   4224   3456 R   0.3   0.1   0:00.04 top
      1 root      20   0  168572  13184   8448 S   0.0   0.2   0:02.31 systemd

Es un programa interactivo, como less o man: ocupa la terminal hasta que se sale con q. La pantalla tiene dos partes. Las cinco líneas de arriba resumen el sistema entero:

LíneaInforma
top -La hora, cuánto hace que arrancó el sistema, los usuarios conectados y la carga media.
TasksLa cantidad de procesos, repartidos por estado.
%Cpu(s)En qué se gasta el tiempo del procesador.
MiB MemLa memoria física: total, libre, usada, y la dedicada a caché.
MiB SwapEl área de intercambio en disco, y la memoria realmente disponible.

La línea Tasks confirma lo dicho sobre los estados: 287 procesos, uno en ejecución y 286 durmiendo. En la del procesador, los dos valores que importan a primera vista son los de los extremos:

SiglaPorcentaje del tiempo en que el procesador…
usEjecuta programas de los usuarios.
syEjecuta código del kernel, el sistema.
niEjecuta programas con prioridad rebajada.
idEstá desocupado (idle).
waEspera al disco. Un valor alto y sostenido indica que el cuello de botella es el almacenamiento, no el procesador.
hi, si, stAtiende interrupciones; o, en una máquina virtual, le fue quitado por otra.

Con 95.6 id, el procesador pasa el 95 % del tiempo sin nada que hacer. La carga media, load average, lo dice de otra manera: sus tres números son el promedio de procesos que quisieron usar el procesador en el último minuto, en los últimos cinco y en los últimos quince. Se interpretan comparándolos con la cantidad de núcleos, que informa el comando nproc: una carga de 4 es plena ocupación en un equipo de cuatro núcleos, y saturación en uno de dos. El tema 37 vuelve sobre estos datos, y sobre la memoria.

La parte de abajo es la lista de procesos, con columnas parecidas a las de ps aux:

ColumnaContieneEn ps
PR, NILa prioridad, y el valor de cortesía que la ajusta.pri, ni
VIRTLa memoria virtual.VSZ
RESLa memoria residente: la que ocupa de verdad.RSS
SHRLa parte de esa memoria que comparte con otros procesos.—
SEl estado.STAT
%CPUEl procesador usado desde la última actualización.Promedio de toda la vida
TIME+El tiempo de procesador acumulado, con centésimas.TIME

La diferencia de la penúltima fila es la razón de ser de top: su %CPU es actual. El proceso que está frenando la máquina aparece arriba de todo, en el momento. Ese porcentaje se mide respecto de un núcleo: un programa que usa dos núcleos a pleno figura con 200 %, sin que haya ningún error.

11. Manejar top

top se maneja con teclas sueltas, sin Intro, y distingue mayúsculas de minúsculas. Las que cambian el orden son las más usadas:

TeclaEfecto
qSalir.
hLa ayuda, con todas las teclas.
POrdenar por uso de procesador. Es el orden inicial.
MOrdenar por uso de memoria.
TOrdenar por tiempo de procesador acumulado.
NOrdenar por PID.
1Mostrar una línea por cada núcleo, en lugar del promedio.
cAlternar entre el nombre del programa y la línea de comandos completa.
uPide un nombre de usuario y muestra solo sus procesos.
VVista de árbol.
e, ECambiar la unidad de la memoria: en la lista; en el resumen.
dCambiar el intervalo de actualización, que es de 3 segundos.
EspacioActualizar ya.
kEnviar una señal a un proceso, para terminarlo. Tema 33.
rCambiar la prioridad de un proceso.

El uso típico lleva diez segundos. La máquina está lenta: se ejecuta top, se mira la primera línea de la lista para ver quién ocupa el procesador, se pulsa M para ver quién ocupa la memoria, se anota el PID y se sale con q.

top acepta también opciones al lanzarlo, y una de ellas lo convierte en un comando común, apto para tuberías y redirecciones:

ComandoEfecto
top -u anaSolo los procesos de un usuario.
top -p 3187,6950Solo esos procesos: para vigilar uno en particular.
top -d 1Actualiza cada segundo.
top -o %MEMEmpieza ordenado por memoria.
top -b -n 1Modo por lotes (batch): escribe una sola pantalla como texto y termina.
terminal: top como filtro
$ top -b -n 1 | head -n 5 > /tmp/estado.txt     # guardar el resumen del sistema
$ top -b -n 1 | sed -n '7,10p'                 # el encabezado y los tres primeros procesos
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   5120 ana       20   0 3412560 778240 201344 S   6.2   9.7  14:03.02 firefox
   2954 ana       20   0 4712340 389120 142208 S   0.0   4.8   9:15.31 gnome-shell
   7493 ana       20   0   13204   4224   3456 R   0.0   0.1   0:00.01 top

Sin -b, top dentro de una tubería produce una salida llena de códigos de control, porque sigue creyendo que dibuja en una pantalla.

12. htop

top está en todos los sistemas, y su interfaz es la de 1984. htop hace el mismo trabajo con una presentación moderna: colores, barras, desplazamiento con las flechas y manejo con el ratón. No siempre viene instalado; en Ubuntu se agrega con sudo apt install htop.

terminal: la pantalla de htop
$ htop
    0[||||                      6.5%]   Tasks: 121, 412 thr; 1 running
    1[||                        2.6%]   Load average: 0.42 0.35 0.30
    2[|||                       4.0%]   Uptime: 12:32:40
    3[|                         1.3%]
  Mem[|||||||||||||      3.32G/7.65G]
  Swp[                      0K/2.00G]

    PID USER       PRI  NI  VIRT   RES   SHR S  CPU% MEM%   TIME+  Command
   5120 ana         20   0 3332M  760M  196M S   6.3  9.7 14:03.40 /usr/lib/firefox/firefox
   2954 ana         20   0 4602M  380M  138M S   2.0  4.8  9:15.52 /usr/bin/gnome-shell
   3170 ana         20   0  549M 56752 42500 S   0.7  0.7  0:27.90 /usr/libexec/gnome-terminal-server
   7501 ana         20   0 10840  4480  3328 R   0.7  0.1  0:00.06 htop
F1Help  F2Setup  F3Search F4Filter F5Tree  F6SortBy F7Nice - F8Nice + F9Kill  F10Quit

Arriba, una barra por cada núcleo del procesador, y otras dos para la memoria y el intercambio: el estado del sistema se entiende de un vistazo, sin leer cifras. Abajo, la última línea recuerda en todo momento qué hace cada tecla de función, de modo que no hay nada que memorizar.

TeclaEfecto
Flechas, RePág, AvPágRecorrer la lista. Con las flechas laterales se ve el resto de las líneas largas.
F3 o /Buscar un proceso por nombre.
F4 o \Filtrar: dejar a la vista solo los que coinciden con un texto.
F5 o tVista de árbol: cada proceso bajo su padre.
F6Elegir la columna de orden. También se puede pulsar su título con el ratón.
uMostrar solo los procesos de un usuario.
HMostrar u ocultar los hilos de cada proceso.
EspacioMarcar un proceso, para actuar sobre varios a la vez.
F9 o kEnviar una señal al proceso seleccionado. Tema 33.
F2Configurar qué medidores y qué columnas se muestran.
F10 o qSalir.

La diferencia de fondo con top es que en htop se selecciona un proceso moviéndose por la lista, en lugar de escribir su PID. Se busca con F3, se lo ve en su lugar del árbol con F5, y se actúa sobre él. Para explorar un sistema es la herramienta más cómoda de las tres.

pstophtop
MuestraUn instanteEl sistema en vivoEl sistema en vivo
Su salidaTexto, para tuberíasPantalla completa; texto con -bPantalla completa
Está instaladoSiempreSiempreHay que instalarlo
Conviene paraBuscar, contar, y usar en scriptsVer qué consume ahora, en cualquier máquinaExplorar con comodidad

La tercera fila decide más de lo que parece. En un servidor ajeno al que se entra por primera vez, o en un sistema mínimo, puede no haber htop ni permiso para instalarlo. ps y top están siempre, y por eso hay que saber usarlos.

13. /proc: de dónde sale todo

Ninguna de estas herramientas tiene un acceso privilegiado al kernel. Todas leen el mismo lugar, que conocimos en el tema 8: el directorio /proc, donde el kernel publica su estado en forma de archivos. Allí hay un subdirectorio por cada proceso, con su PID como nombre.

terminal
$ ls -d /proc/[0-9]* | wc -l                # un directorio por proceso
287
$ ls -l /proc/$$/cwd /proc/$$/exe           # el directorio actual y el programa de la shell
lrwxrwxrwx 1 ana ana 0 oct 12 21:40 /proc/3187/cwd -> /home/ana/practica
lrwxrwxrwx 1 ana ana 0 oct 12 21:40 /proc/3187/exe -> /usr/bin/bash
$ grep -E '^(Name|State|Pid|PPid|VmRSS)' /proc/$$/status
Name:	bash
State:	S (sleeping)
Pid:	3187
PPid:	3170
VmRSS:	    5376 kB

Ahí están, sin intermediarios, los datos que ps ordenó en columnas: el nombre, el estado S, el PID y el PPID, y los 5376 kilobytes de memoria residente de la sección 5.

ArchivoContiene
/proc/PID/statusLa ficha del proceso, en formato legible.
/proc/PID/cmdlineLa línea de comandos, con los argumentos separados por caracteres nulos.
/proc/PID/cwdUn enlace a su directorio actual.
/proc/PID/exeUn enlace al archivo del programa que ejecuta.
/proc/PID/environSus variables de entorno.
/proc/PID/fdSus descriptores abiertos: el directorio que usamos en el tema 22.

Dos de ellos responden preguntas que ps no contesta de manera directa. cwd dice en qué directorio está trabajando un proceso, que es lo que hay que saber cuando un programa escribe un archivo «en algún lado». Y exe dice qué archivo exacto se está ejecutando, cuando hay varias versiones de un programa instaladas.

Solo se pueden leer por completo los procesos propios: los directorios de los ajenos existen, pero varios de sus archivos responden Permission denied. Es coherente con el resto del sistema: ver qué procesos tiene otro usuario está permitido; mirar dentro de ellos, no.

14. Recetas y errores comunes

Quiero…Comando
Ver todos los procesosps aux | less
Saber si un programa está en ejecución, y su PIDpgrep -a nombre
Ver la ficha de un proceso del que conozco el PIDps -fp PID
Los diez que más memoria ocupanps aux --sort=-%mem | head -n 11
Los diez que más procesador usaronps aux --sort=-%cpu | head -n 11
Qué está usando el procesador ahoratop
Los procesos de un usuariops -fu usuario
Cuántos procesos hayps -e --no-headers | wc -l
Quién es el padre de un procesops -o ppid= -p PID
La cadena de antepasados de un procesopstree -ps PID
Cuánto hace que se inició un procesops -o etime= -p PID
En qué directorio trabaja un procesols -l /proc/PID/cwd
Vigilar un proceso en particulartop -p PID
Guardar el estado del sistema en un archivotop -b -n 1 > estado.txt
SíntomaCausaSolución
ps muestra solo dos o tres líneas.Sin opciones, lista solo los procesos de esta terminal.ps aux o ps -ef.
Una advertencia al escribir ps -aux.Se mezclaron dos estilos de opciones.ps aux, sin guion.
Las líneas de comandos salen cortadas.ps las ajusta al ancho de la terminal.ps auxww, o ps aux | less -S.
Al buscar con grep aparece el propio grep.Su línea de comandos contiene lo buscado.pgrep.
pgrep no encuentra un script que está en marcha.Compara solo el nombre del programa, que es el del intérprete.pgrep -f.
pgrep encuentra procesos de más.El patrón coincide con una parte del nombre.pgrep -x.
Un proceso lleva horas y su TIME es 0:00.TIME es tiempo de procesador, no de reloj.Mirar etime o START.
El %CPU de ps no coincide con el de top.ps promedia toda la vida del proceso; top mide el último intervalo.Para el presente, top.
Un proceso figura con 250 % de procesador.El porcentaje se mide sobre un núcleo, y el proceso usa varios.No es un error.
La memoria «libre» es muy poca.Linux usa la memoria sobrante como caché de disco, y la cede cuando hace falta.Mirar avail Mem, no free.
top en una tubería escribe caracteres extraños.Sigue en modo interactivo.top -b -n 1.
htop: command not foundNo está instalado.sudo apt install htop.

La referencia del tema:

Se escribeQué hace
echo $$Muestra el PID de la shell.
psLista los procesos de esta terminal.
ps auxTodos los procesos, con su consumo.
ps -efTodos los procesos, con su padre.
ps -o pid,ppid,cmdElige las columnas.
ps -u, -p, -CSelecciona por usuario, por PID, por nombre de programa.
ps … --sort=-%memOrdena, de mayor a menor.
ps -ef --forest, pstree -pMuestra el árbol de procesos.
pgrep nombre, pgrep -a, pgrep -fBusca procesos y da sus PID.
pidof programaDa los PID de un programa.
topMonitor en vivo. P, M, 1, q.
top -b -n 1Una pantalla de top, como texto.
htopMonitor en vivo, más cómodo.
/proc/PID/Los datos de un proceso, como archivos.

Queda el sleep de la segunda terminal. Ve a esa ventana y pulsa Ctrl+C: el indicador vuelve, y pgrep sleep ya no encuentra nada. Acabas de enviarle una señal a un proceso. En este tema solo miramos; en el tema 33 intervenimos: lanzar programas en segundo plano, pausarlos, reanudarlos y terminarlos, incluso los que no responden.

15. Resumen

16. Preguntas de repaso

Intenta responder cada una antes de abrir la respuesta.

1. ¿Qué diferencia hay entre un programa y un proceso?

Un programa es un archivo con instrucciones, guardado en el disco. Un proceso es ese programa en ejecución, cargado en memoria. Un programa puede tener varios procesos a la vez.

2. ¿Qué son el PID y el PPID?

El PID es el número que identifica a un proceso. El PPID es el PID de su padre, el proceso que lo lanzó.

3. ¿Qué muestra echo $$?

El PID de la shell en la que se ejecuta.

4. ps, sin opciones, muestra dos líneas. ¿Por qué tan pocas, y por qué aparece el propio ps?

Porque solo lista los procesos del usuario conectados a la terminal actual. Y ps aparece porque, mientras arma la lista, es uno de ellos.

5. ¿Qué diferencia hay entre ps aux y ps -ef?

Las dos listan todos los procesos. ps aux muestra el consumo de procesador y memoria y el estado; ps -ef muestra el PPID.

6. ¿Qué indican un ? en la columna TTY y un nombre entre corchetes en COMMAND?

El signo de interrogación, que el proceso no está conectado a ninguna terminal. Los corchetes, que es un hilo del kernel y no un programa del disco.

7. ¿Qué diferencia hay entre VSZ y RSS?

VSZ es la memoria virtual, todo lo que el proceso tiene reservado. RSS es la memoria residente, lo que ocupa realmente en la memoria física.

8. Una shell abierta hace cinco horas muestra TIME igual a 00:00:00. ¿Es un error?

No. TIME es el tiempo de procesador consumido, y la shell pasó casi todo ese tiempo esperando. El tiempo transcurrido se ve con ps -o etime.

9. ¿Qué significan los estados R, S, T y Z?

En ejecución o listo para ejecutar; durmiendo, a la espera de un acontecimiento; detenido; y zombie, terminado pero aún no recogido por su padre.

10. Escribe el comando que muestra los cinco procesos que más memoria ocupan.

ps aux --sort=-%mem | head -n 6: seis líneas, contando el encabezado.

11. ¿Cuál es el proceso de PID 1, y qué lugar ocupa?

Es el primero que el kernel inicia al arrancar, systemd en las distribuciones actuales. Es la raíz del árbol: todos los demás descienden de él.

12. ¿Por qué conviene pgrep firefox antes que ps aux | grep firefox?

Porque pgrep devuelve directamente los PID y no se incluye a sí mismo en el resultado, como sí hace grep.

13. pgrep respaldo no encuentra el script respaldo.sh, que está en ejecución. ¿Por qué, y cómo se corrige?

Porque pgrep compara con el nombre del programa, que en un script es el del intérprete, bash. Con pgrep -f respaldo se busca en la línea de comandos completa.

14. ¿En qué se diferencia el %CPU de ps del de top?

El de ps es un promedio de toda la vida del proceso. El de top corresponde al intervalo desde la última actualización: muestra el consumo actual.

15. ¿Para qué sirve top -b -n 1?

Para obtener una sola pantalla de top como texto común, que se puede enviar a una tubería o guardar en un archivo.

Para practicar

  1. Ejecuta echo $$ y ps en dos terminales distintas. Compara los PID y la columna TTY. Luego, desde una, muestra los procesos de la otra con ps -t.
  2. Cuenta cuántos procesos hay en tu sistema, cuántos son tuyos, cuántos de root y cuántos son hilos del kernel (ps -e -o cmd= | grep -c '^\[').
  3. Con ps -eo y --sort, obtén los cinco procesos con más memoria residente y los cinco con más tiempo de procesador acumulado. ¿Coinciden?
  4. Lista con ps aux y awk solo el usuario, el PID y el comando de los procesos cuyo %MEM supera el 1 %.
  5. Cuenta cuántos procesos hay en cada estado: ps -eo stat= | cut -c1 | sort | uniq -c. Explica el resultado.
  6. Ejecuta sleep 600 en otra terminal. Encuéntralo con pgrep -a, averigua su padre, su estado, cuánto hace que se inició y en qué directorio trabaja. Compruébalo en /proc.
  7. Recorre el árbol con pstree -p | less y localiza tu shell. Compara con pstree -ps $$ y con ps -ef --forest | less.
  8. Abre top. Ordena por memoria, luego por tiempo acumulado; muestra los núcleos por separado; limita la lista a tu usuario; cambia el intervalo a un segundo. Sal con q.
  9. Con top -b -n 1 y los filtros del bloque anterior, extrae solo la carga media del sistema, y luego solo los nombres de los cinco procesos que más procesador usan.
  10. Instala htop. Busca tu shell con F3, activa la vista de árbol, filtra por bash y ordena por memoria. ¿Qué tareas te resultaron más fáciles que en top?