Procesos y servicios

Todo lo que corre, quién lo levanta y cómo detenerlo

Marco González Luengo

Tabla de contenidos
  1. Procesos
  2. Ver los procesos
  3. Primer y segundo plano
  4. Señales
  5. Servicios y systemd
  6. Targets: hasta dónde arrancar
  7. Logs: qué pasó
  8. Instalar programas
  9. Ejercicios

Cada programa que se ejecuta es un proceso. Ahora mismo, en tu equipo, hay cientos: tu navegador, la terminal, y muchos que no ves, trabajando en segundo plano.

Procesos

Un proceso es un programa en ejecución: el código, más la memoria que usa, los archivos que tiene abiertos y su estado. El mismo programa puede estar corriendo varias veces, y cada una es un proceso distinto.

Cada proceso tiene:

El primer proceso, con PID 1, es systemd, que el kernel lanza al arrancar. Todos los demás descienden de él.

pstree -p | head    # el árbol de procesos, con sus PID

Ver los procesos

ps           # los procesos de esta terminal
ps aux       # todos los procesos del sistema, de todos los usuarios
ps aux | grep firefox    # buscar uno en particular
pgrep -a firefox         # lo mismo, más directo

ps aux muestra una línea por proceso:

USER    PID %CPU %MEM    VSZ   RSS TTY   STAT START  TIME COMMAND
ana    4312  6.5  4.0 152013 30726 ?     Sl   12:23  3:03 /usr/bin/firefox

Las columnas que más importan:

Para verlos en vivo, ordenados por consumo, está top (se sale con q), o htop, que es más amigable y hay que instalarlo.

Primer y segundo plano

Normalmente, un comando ocupa la terminal hasta que termina: corre en primer plano. Con & al final, corre en segundo plano y la terminal queda libre:

sleep 300 &      # corre en segundo plano
jobs             # lista los trabajos de esta terminal
fg %1            # trae el trabajo 1 al primer plano

Si un programa ya está corriendo en primer plano, Ctrl + Z lo suspende (lo congela), y después se puede continuar:

bg %1            # sigue corriendo, en segundo plano
fg %1            # sigue corriendo, en primer plano

Señales

Los procesos se comunican con señales: avisos que el sistema le envía a un proceso para que haga algo. Las más comunes:

Señal Número Qué hace Cómo se envía
SIGTERM 15 Pide terminar, de forma ordenada kill PID
SIGKILL 9 Termina de golpe; no se puede ignorar kill -9 PID
SIGINT 2 Interrumpe Ctrl + C
SIGTSTP 20 Suspende (el programa lo puede ignorar) Ctrl + Z
SIGSTOP 19 Detiene; no se puede ignorar kill -STOP PID
SIGCONT 18 Continúa un proceso detenido kill -CONT PID
SIGHUP 1 "Se cortó la terminal"; muchos servicios lo usan para recargar su configuración kill -HUP PID

A pesar del nombre, kill no solo mata: envía cualquier señal. Por defecto envía SIGTERM.

kill 4312             # pide a 4312 que termine
kill -9 4312          # lo termina a la fuerza
pkill firefox         # envía la señal por nombre, sin buscar el PID

Primero siempre kill a secas. SIGTERM le da al programa la oportunidad de guardar su trabajo y cerrar sus archivos. kill -9 es el último recurso, para cuando no responde: el programa muere sin poder limpiar nada.

La lista completa está en man 7 signal o con kill -l.

Servicios y systemd

Un servicio (o demonio, daemon) es un proceso que corre en segundo plano, sin terminal, esperando trabajo: el servidor web, SSH, la impresión, el reloj.

Los servicios los levanta y administra systemd. Cada servicio se describe en una unidad (unit), un archivo .service en /usr/lib/systemd/system/ (los que instalan los paquetes) o en /etc/systemd/system/ (los propios o modificados).

Todo se maneja con systemctl:

systemctl status sshd          # estado del servicio: si corre, desde cuándo, últimos logs
sudo systemctl start sshd      # lo inicia ahora
sudo systemctl stop sshd       # lo detiene ahora
sudo systemctl restart sshd    # lo reinicia
sudo systemctl enable sshd     # que se inicie solo al arrancar
sudo systemctl disable sshd    # que ya no se inicie al arrancar
sudo systemctl enable --now sshd   # habilita e inicia, de una vez

Es importante no confundir estas dos parejas:

Para listar servicios:

systemctl list-units --type=service                       # los que están cargados
systemctl list-unit-files --type=service --state=enabled  # los habilitados al arrancar

(El nombre del servicio puede variar entre distribuciones: el de SSH es sshd en Fedora y ssh en Debian y Ubuntu.)

Targets: hasta dónde arrancar

Un target es un grupo de unidades que definen un "estado" del sistema. Los principales:

Target Qué hay
rescue.target Modo de rescate: solo root, lo mínimo, sin red
multi-user.target Sistema completo para varios usuarios, con red, en modo texto
graphical.target Todo lo anterior, más el entorno gráfico
poweroff.target Apagado
reboot.target Reinicio
systemctl get-default                            # con qué target arranca
sudo systemctl set-default multi-user.target     # arrancar en modo texto
sudo systemctl isolate multi-user.target         # cambiar ahora, sin reiniciar
systemctl reboot                                 # reiniciar
systemctl poweroff                               # apagar

Logs: qué pasó

Los servicios y el kernel van dejando registro de lo que hacen. En systemd, todo va al journal, y se consulta con journalctl:

journalctl                  # todo, desde lo más antiguo
journalctl -e               # salta al final
journalctl -f               # muestra lo nuevo en vivo (como tail -f)
journalctl -u sshd          # solo un servicio
journalctl -b               # desde el último arranque
journalctl -p err           # solo errores y peores
journalctl --since "1 hour ago"

Varios programas siguen escribiendo además archivos de texto en /var/log, y se leen con less o tail -f. Si la distribución tiene rsyslog instalado, los mensajes generales van a /var/log/messages (Red Hat, Fedora) o /var/log/syslog (Debian, Ubuntu), y los de autenticación a /var/log/secure o /var/log/auth.log.

Instalar programas

Los programas se instalan con el gestor de paquetes de la distribución, que descarga el programa y todo lo que necesita desde repositorios confiables:

Acción Fedora / Red Hat Debian / Ubuntu
Instalar sudo dnf install paquete sudo apt install paquete
Actualizar todo sudo dnf upgrade sudo apt update && sudo apt upgrade
Buscar dnf search palabra apt search palabra
Desinstalar sudo dnf remove paquete sudo apt remove paquete

Instalar un servicio no lo deja corriendo: después hay que habilitarlo con systemctl enable --now.

Ejercicios

¿Qué muestra ps? ¿Y ps aux?

ps muestra los procesos asociados a la terminal actual: normalmente la shell y lo que lanzaste desde ella.

ps aux muestra todos los procesos del sistema: de todos los usuarios (a), con el usuario dueño (u) e incluyendo los que no tienen terminal, como los servicios (x). Para cada uno indica PID, consumo de CPU y memoria, estado y el comando.

¿Con qué "nivel" arranca el sistema, y qué significa cada uno?

Con systemd, el sistema arranca en un target. Se consulta con systemctl get-default:

  • rescue.target: modo de rescate, solo root.
  • multi-user.target: multiusuario completo, con red, en modo texto.
  • graphical.target: lo anterior más el entorno gráfico.
  • poweroff.target y reboot.target: apagar y reiniciar.

Equivalen a los antiguos runlevels de init: 0 apagar, 1 monousuario, 3 multiusuario, 5 gráfico y 6 reiniciar (ver la nota histórica en Servicios y systemd).

¿Qué hacen systemctl reboot y systemctl enable?
  • systemctl reboot reinicia el equipo. El clásico comando reboot sigue existiendo, pero hoy es un atajo a systemctl.
  • systemctl enable servicio configura un servicio para que se inicie solo al arrancar. No lo inicia en el momento (para eso, start, o enable --now).

Ambos requieren permisos de administrador. En un escritorio, reiniciar se permite al usuario que está frente al equipo.

¿Cómo listas los servicios que no están habilitados, y guardas la lista en un archivo?
systemctl list-unit-files --type=service --state=disabled > servicios-deshabilitados.txt

systemctl lista los archivos de unidad de tipo servicio con estado disabled, y > manda esa salida al archivo.

Encuentra los servicios que se inician con el entorno gráfico y deshabilita uno.

Los servicios habilitados al arrancar se listan con:

systemctl list-unit-files --type=service --state=enabled

Para ver todo lo que arrastra el target gráfico: systemctl list-dependencies graphical.target.

Elegido uno (por ejemplo, cups, el servicio de impresión), se detiene y deshabilita de una vez:

sudo systemctl disable --now cups
¿Dónde quedan los mensajes del sistema (los logs)?

En el journal de systemd, que se consulta con journalctl. Además, muchos programas escriben archivos de texto en /var/log, y si está instalado rsyslog, los mensajes generales quedan también en /var/log/messages (Red Hat, Fedora) o /var/log/syslog (Debian, Ubuntu).

¿Qué hace tail archivo? ¿Y tail -f archivo?

tail muestra las últimas 10 líneas de un archivo (con -n 50, las últimas 50).

tail -f (de follow) muestra las últimas líneas y se queda esperando: cada línea nueva que se agrega al archivo aparece en pantalla. Es la forma clásica de ver un log en tiempo real. Se sale con Ctrl + C. Para el journal, el equivalente es journalctl -f.

¿Cómo monitoreas en vivo los eventos que ocurren en el sistema?
journalctl -f

Muestra los mensajes nuevos del journal a medida que llegan, de todos los servicios y del kernel. Para uno solo, journalctl -f -u servicio.

Necesitas monitorear en vivo los accesos por SSH y guardarlos en un archivo. ¿Cómo lo haces?
sudo journalctl -f -u sshd >> accesos.log

-f sigue los mensajes nuevos, -u sshd filtra el servicio de SSH (ssh en Debian y Ubuntu) y >> los agrega al archivo. Si quieres verlos en pantalla y guardarlos a la vez, usa tee: sudo journalctl -f -u sshd | tee -a accesos.log.

Con rsyslog, también se puede seguir el archivo de autenticación: sudo tail -f /var/log/secure >> accesos.log (o /var/log/auth.log en Debian y Ubuntu).

¿Qué señal pausa un programa? Escribe el comando completo.

SIGSTOP:

kill -STOP 4312      # el proceso 4312 queda detenido
kill -CONT 4312      # continúa donde quedó

Si el programa está en primer plano en tu terminal, Ctrl + Z hace algo parecido (envía SIGTSTP), y después se continúa con fg o bg.

Ojo: poner & al final de un comando no lo pausa, sino que lo lanza en segundo plano, corriendo.

Un proceso está usando muchísima CPU o memoria. ¿Cuál es la forma aconsejable de terminarlo?
  1. Identificarlo: top (o htop) lo muestra arriba de la lista, con su PID.
  2. Pedirle que termine de forma ordenada: kill PID, que envía SIGTERM.
  3. Si después de unos segundos sigue ahí, forzarlo: kill -9 PID, que envía SIGKILL.

Si el proceso es de otro usuario o de un servicio, hace falta sudo. Y si es un servicio, lo correcto es detenerlo con sudo systemctl stop servicio.

¿Qué pasa con systemctl stop sshd? ¿Es lo mismo que systemctl disable sshd?

No es lo mismo:

  • systemctl stop sshd detiene el servicio ahora. Pero si está habilitado, al reiniciar el equipo vuelve a iniciarse.
  • systemctl disable sshd deshabilita el inicio automático: en el próximo arranque ya no se inicia. Pero si está corriendo ahora, sigue corriendo.

Para las dos cosas a la vez: sudo systemctl disable --now sshd.

¿Qué hace sudo dnf install httpd php mariadb-server?

Instala, con sus dependencias, tres paquetes: el servidor web Apache (httpd), el lenguaje PHP y el servidor de bases de datos MariaDB (el reemplazo libre de MySQL). En Debian y Ubuntu, el equivalente es sudo apt install apache2 php mariadb-server.

Después, para que los servicios queden corriendo:

sudo systemctl enable --now httpd mariadb
¿Cómo harías que los logs de un programa queden en otro archivo?

Depende de a dónde escribe el programa:

  • Si escribe al journal (los servicios de systemd), sus mensajes se pueden exportar cuando se necesiten: journalctl -u servicio > servicio.log.
  • Si se usa rsyslog, se agrega una regla en un archivo dentro de /etc/rsyslog.d/ que envíe ciertos mensajes a un archivo propio, y se reinicia con sudo systemctl restart rsyslog.
  • Muchos programas (Apache, por ejemplo) tienen en su configuración una opción que dice en qué archivo escriben su log.
¿Dónde se definen hoy los servicios? ¿Qué había antes en /etc/rc.d/init.d?

Hoy, cada servicio es un archivo de unidad de systemd: los que instalan los paquetes están en /usr/lib/systemd/system/ y los creados o modificados por el administrador en /etc/systemd/system/. Se puede ver uno con systemctl cat sshd.

Antes de systemd, en /etc/rc.d/init.d (o /etc/init.d) había scripts de shell, uno por servicio, que aceptaban argumentos como start, stop y restart.


Sigue con Redes en Linux.