🖇️
Apuntes LPIC-1
  • General
  • Ejercicios de utilidades
  • 1️Examen 101
    • Tema 101: Arquitectura del Sistema
    • Tema 102: Instalación de Linux y gestión de paquetes
    • Tema 103: Comandos GNU y Unix
      • 103.1 - Trabajar desde la línea de comandos
      • 103.2 - Procesar secuencias de texto usando filtros
        • Listado de texto plano
        • Ejercicios 103.2
      • 103.3 - Administración básica de archivos
      • 103.4 - Uso de secuencias de texto, tuberías y redireccionamientos
      • 103.5 - Crear, supervisar y matar procesos
        • 🚧Ejercicios 103.5
      • 103.6 Modificar la prioridad de ejecución de los procesos
      • 103.7 - Realizar búsquedas en archivos de texto usando expresiones regulares
      • 103.8 - Edición básica de archivos
    • Tema 104: Dispositivos, sistemas de archivos Linux y el estándar de jerarquía de archivos
    • Test prueba
  • 2️Examen 102
    • Tema 105: Shells y scripts
    • Tema 106: Interfaces de usuario y escritorios
    • Tema 107: Tareas administrativas
    • Tema 108: Servicios esenciales del sistema
    • Tema 109: Fundamentos de redes
    • Tema 110: Seguridad
Powered by GitBook
On this page
  • Contenidos
  • Control de trabajos
  • Estado del trabajo: suspensión, primer plano y segundo plano
  • Trabajos separados: nohup
  • Monitorización de procesos
  • Envío de señales a procesos: kill
  • Top y ps
  • El área de tareas en top: campos y columnas
  • Visualización de procesos estáticos
  • Organización de ventanas
  1. Examen 101
  2. Tema 103: Comandos GNU y Unix

103.5 - Crear, supervisar y matar procesos

Importancia

4

Descripción

El candidato debe ser capaz de realizar una gestión básica de los procesos.

Áreas de conocimiento clave:

  • Ejecutar trabajos en primer y segundo plano.

  • Enviar señales a los programas para que continúen ejecutándose después del cierre de sesión.

  • Supervisar procesos activos.

  • Seleccionar y ordenar procesos para su visualización.

  • Enviar señales a los procesos.

Contenidos

Control de trabajos

Los trabajos (Jobs) son procesos que se han iniciado de forma interactiva a través de un terminal, enviados a un segundo plano y aún no han finalizado la ejecución. Puedes conocer los trabajos activos (y su estado) en Linux ejecutando jobs.

El comando jobs anterior no produjo ningún resultado, lo que significa que no hay trabajos activos en este momento. Creemos nuestro primer trabajo ejecutando un comando que tarde un poco en finalizar la ejecución (el comando sleep con un parámetro de 60) y, mientras se ejecuta, presione Ctrl + Z:

sleep 60
^Z
#Resultado: [1]+ Stopped sleep 60

La ejecución del comando se ha detenido (o, mejor dicho, suspendido) y el símbolo del sistema vuelve a estar disponible, si pruebas a ejecutar jobs otra vez, buscará trabajos por segunda vez y encontrará el suspendido.

En el resultado verás [1], es el ID del trabajo y se puede utilizar, precedido por % para cambiar el estado del trabajo mediante las utilidades bg y kill más adelante).

Y el signo + indica el trabajo actual predeterminado (es decir, el último suspendido o enviado al segundo plano). El trabajo anterior está marcado con un signo menos (-). Cualquier otro trabajo anterior no está marcado.

Otros parámetros del comando son:

jobs -l #Muestra la ID del proceso (PID) justo antes del estado.
jobs -n #Muestra solo los procesos que han cambiado de estado desde la última notificación
jobs -p #Lista los IDs de procesos.
jobs -r #Lista solo los procesos en ejecución.
jobs -s #Lista solamente los trabajos detenidos (o suspendidos)

Recuerda que un trabajo tiene un ID de trabajo y un ID de proceso (PID).

Especificaciones de trabajos

El comando jobs, así como otras utilidades como fg, bg y kill (que verá en la siguiente sección) necesitan una especificación de trabajo (o jobspec) para actuar sobre un trabajo en particular. Como acabamos de ver, esto puede ser, y normalmente es, el ID del trabajo precedido por %. Sin embargo, otras especificaciones de trabajo también son posibles. Echemos un vistazo a ellos:

  • %n -> Trabajo cuyo número de identificación es n .

  • %str -> Trabajo cuya línea de comando comienza con str .

  • %?str -> Trabajo cuya línea de comando contiene str .

  • %+ o %% -> Trabajo actual (el último que se inició en segundo plano o suspendido del primer plano).

  • %- -> Trabajo anterior (el que era % + antes del predeterminado, el actual).

Por ejemplo:

#Planteamos:
sleep 100
sleep 200
sleep 300

#Y ahora vammos a ver ejemplos
kill %3 # Esto matará el trabajo con ID 3.
kill %sleep  # Esto matará el primer trabajo que comienza con 'sleep'.
kill %?200  # Esto matará el trabajo que contiene '200'.

fg %+  # Esto traerá al primer plano el trabajo actual (ID 3).
fg %-  # Esto traerá al primer plano el trabajo anterior (ID 2).

Estado del trabajo: suspensión, primer plano y segundo plano

Una vez que un trabajo está en segundo plano o ha sido suspendido, podemos hacer cualquiera de estas tres cosas:

  1. Llevarlo al primer plano con fg (foreground):

fg %1 
#sleep 60

fg mueve el trabajo especificado al primer plano y lo convierte en el trabajo actual. Ahora podemos esperar hasta que termine, detenerlo nuevamente con Ctrl+Z o terminarlo con Ctrl+C.

  1. Llevarlo a un segundo plano con bg (background):

bg %1
#[1]+ sleep 60 &

Una vez en segundo plano, el trabajo se puede volver a poner en primer plano con fg o matar (ver más abajo). Ten en cuenta el signo (&) que significa que el trabajo se ha enviado a segundo plano. De hecho, también puede usar el signo y comenzar un proceso directamente en segundo plano:

sleep 100 &
  1. Termine con una señal SIGTERM con kill:

kill %2

Para asegurarnos de que el trabajo ha finalizado, ejecuta nuevamente jobs.

Trabajos separados: nohup

Los trabajos que hemos visto en las secciones anteriores se adjuntaron a la sesión del usuario que los invocó. Eso significa que si la sesión se termina, los trabajos desaparecen. Sin embargo, es posible separar los trabajos de las sesiones y hacer que se ejecuten incluso después de cerrar la sesión. Esto se logra con el comando nohup (“no hangup”).

Separemos el trabajo en segundo plano ping localhost de la sesión actual:

nohup ping localhost & 
#[1] 1251 
#$ nohup: ignoring input and appending output to 'nohup.out' 
^C

La salida nos muestra la ID del trabajo ([1]) y el PID ( 1251), seguido de un mensaje que nos informa sobre el archivo nohup.out. Este es el archivo predeterminado donde se guardarán stdout y stderr.

Ahora podemos presionar sesión, iniciar otro como Ctrl + C para liberar el símbolo del sistema, cerrar la root y usar tail -f para verificar si el comando se está ejecutando y la salida se está escribiendo en el archivo predeterminado:

exit
# logout
tail -f /home/carol/nohup.out 
#64 bytes from localhost (::1): icmp_seq=3 ttl=64 time=0.070 ms 
#64 bytes from localhost (::1): icmp_seq=4 ttl=64 time=0.068 ms 
#64 bytes from localhost (::1): icmp_seq=5 ttl=64 time=0.070 ms 
^C

Si queremos matar el proceso, debemos especificar su PID:

kill 1251

Si te has olvidado del PID del proceso, puedes buscar con ps aux | grep ping

Caso práctico: Cazador de pdfs

Vamos a aprender cómo ejecutar procesos en segundo plano de forma persistente con nohup, incluso si cerramos la terminal. Para hacerlo más interesante, simularemos un "cazador de PDFs" 🔍📂.

1️⃣ Preparación: Creación de archivos PDF de prueba

Primero, asegúrate de estar en tu carpeta de inicio y crea varios archivos PDF:

cd ~
touch reporte1.pdf
touch notas.pdf
touch factura.pdf
touch libro.pdf

Para hacerlo aún más divertido, usa un bucle para crear muchos más de golpe:

for i in {1..200}; do touch "documento_$i.pdf"; done

2️⃣ Búsqueda manual de archivos PDF

Antes de usar nohup, probemos el comando find manualmente para ver qué resultados obtenemos:

find ~ -name "*.pdf"

Este comando busca archivos con la extensión .pdf en tu carpeta de inicio.

3️⃣ Ejecutando la búsqueda con nohup

Ahora vamos a ejecutar la búsqueda, pero asegurándonos de que siga funcionando aunque cerremos la terminal:

nohup find ~ -name "*.pdf" &

El & al final hace que el proceso se ejecute en segundo plano. La salida se guarda por defecto en un archivo llamado nohup.out.

💡 Ejercicio: Abre una nueva terminal y revisa el contenido de nohup.out con:

cat nohup.out

4️⃣ Personalizando la salida

En lugar de dejar que nohup use el archivo predeterminado, redirigiremos la salida a un archivo específico:

nohup find ~ -name "*.pdf" > resultados_pdf.out &

Ahora, revisemos si el archivo resultados_pdf.out se está generando:

cat resultados_pdf.out

5️⃣ Verificando que el proceso sigue corriendo

Ejecuta este comando para listar los procesos en ejecución y comprobar si find aún está trabajando:

ps aux | grep find

Si el proceso aún está en marcha, significa que nohup lo está manteniendo activo. Si ya terminó, es porque la búsqueda fue rápida.

6️⃣ Deteniendo un proceso en segundo plano (si es necesario)

Si por alguna razón quieres detener la búsqueda antes de que termine, puedes encontrar su ID de proceso (PID) y matarlo:

ps aux | grep find
kill -9 <PID>

(Recuerda reemplazar <PID> con el número de proceso que aparece en la salida del comando ps aux).

Caso práctico: El Contador Secreto de Archivos con nohup

1️⃣ Creando un "laberinto" de archivos 🏗️

Para hacer esto más interesante, primero generaremos varias carpetas con archivos dentro:

mkdir -p mi_experimento/carpeta_{1..5}
for i in {1..20}; do touch mi_experimento/carpeta_$((RANDOM % 5 + 1))/archivo_$i.txt; done

Con esto, habremos creado 5 carpetas y distribuido 20 archivos de forma aleatoria en ellas.

Puedes ver la estructura con ls -R


2️⃣ Contando archivos de forma tradicional

Probemos el comando find manualmente para contar los archivos:

find mi_experimento -type f | wc -l

Esto nos dirá cuántos archivos hay en la carpeta mi_experimento.


3️⃣ Haciendo el conteo persistente con nohup 🚀

Ahora usaremos nohup para contar archivos y asegurarnos de que siga ejecutándose aunque cerremos la terminal:

nohup bash -c 'while true; do find mi_experimento -type f | wc -l ; sleep 10; done' &

El proceso se ejecutará en segundo plano y guardará la cantidad de archivos en conteo_archivos.out.

🔍 Ejercicio:

  • Cierra la terminal y ábrela de nuevo.

  • Verifica si el archivo conteo_archivos.out tiene el resultado con:

    cat conteo_archivos.out

4️⃣ Creando más archivos para ver el efecto de nohup

Mientras el proceso sigue corriendo, agreguemos más archivos:

for i in {21..40}; do touch mi_experimento/carpeta_$((RANDOM % 5 + 1))/archivo_$i.txt; done

Luego, volvamos a revisar el conteo:

cat conteo_archivos.out

¿El resultado ha cambiado? 🤔 Si no, prueba ejecutar de nuevo el comando de conteo.

Pureba ahora a borrar algun archivo y vuelve a revisar.


5️⃣ Para ver los cambios en tiempo real:

tail -f conteo_archivos.out

Para detener el proceso:

ps aux | grep find
kill -9 <PID>

(Recuerda reemplazar <PID> con el número de proceso correcto).


Monitorización de procesos

Un proceso o tarea es una instancia de un programa en ejecución. Por lo tanto, se crean nuevos procesos cada vez que escribe comandos en el terminal. El comando watch ejecuta un programa periódicamente (2 segundos por defecto) y nos permite mirar el cambio de salida del programa con el tiempo. Por ejemplo, podemos monitorear cómo cambia el promedio de carga a medida que se ejecutan más procesos escribiendo watch uptime

El comando se ejecuta hasta que se interrumpe, por lo que deberíamos detenerlo con Ctrl + C. Obtenemos dos líneas como salida: la primera corresponde a watch y nos dice con qué frecuencia se ejecutará el comando ( Every 2.0s: uptime), qué comando/programa mirar ( uptime) así como el comando nombre de host y fecha ( debian: mar 20 de agosto 23:31:27 2019). La segunda línea de salida es el tiempo de actividad e incluye la hora ( 23:31:27), cuánto tiempo ha estado activo el sistema ( up 21 min), el número de usuarios activos ( 1 usuario) y carga promedio del sistema o número de procesos en ejecución o en estado de espera durante los últimos 1, 5 y 15 minutos ( promedio de carga: 0.00, 0.00, 0.00).

Del mismo modo, puedes verificar el uso de la memoria a medida que se crean nuevos procesos con watch free.

Para cambiar el intervalo de actualización para watch usa las opciones -n o --interval más el número de segundos con watch -n 5 free

Envío de señales a procesos: kill

El comando kill, a pesar de su nombre, es un comando que envia señales a procesos. Cada proceso tiene un identificador de proceso único o PID. Una forma de averiguar el PID de un proceso es mediante el comando pgrep o pidof seguido del nombre del proceso:

pgrep sleep
pidof sleep

Similar a pgrep, el comando pkill mata un proceso basado en su nombre:

pkill sleep

Para matar varias instancias del mismo proceso, se puede usar el comando killall

sleep 60 & 
#[1] 1246
sleep 70 & 
#[2] 1247
killall sleep 
[1]- Terminated sleep 60 
[2]+ Terminated sleep 70

Tanto pkill como killall funcionan de la misma manera que kill en que envían una señal de terminación a los procesos especificados. Si no se proporciona ninguna señal, se envía el valor predeterminado de SIGTERM. Sin embargo, kill solo toma un trabajo o una ID de proceso como argumento. Las señales se pueden especificar por nombre, numero o con opciones.

Para que kill funcione de manera similar a pkill o killall (y nos ahorremos los comandos para descubrir los PID primero) podemos usar la sustitución de comandos:

kill -l $(pgrep sleep)

Tambien podemos cerrar los procesos de un usuario (por ejemplo por una sesión abierta descontrolada a un intruso):

killall -u alex

Algunas señales comunes a enviar (recuerda que con kill -l puedes revisarlos todos):

Comando
Señal
Descripción

kill -2

SIGINT

Interrumpir un proceso (Ctrl + C).

kill -9

SIGKILL

Mata el proceso de golpe, es más agresivo, puede dejar procesos "zombie". No hay ningun proceso inmutable para este comando. Último recurso.

kill -15

SIGTERM

termina lo que estas haciendo y finaliza, reubica todos los procesos que dependen de él a otros procesos.

kill -18

SIGCONT

continue, reanuda un proceso en pausa pero lo hace en el terminal desde que has lanzado el comando por lo que el ctrl+C ya no hace caso. Se ha pasado a segundo plano. Si queremos reanudar ponemos manualmente el kill -2

kill -19

SIGSTOP

stop, proceso en pausa (Ctrl+Z), por ejemplo con el buscaminas o el pìng. El proceso podemos seguir viéndolo.

Top y ps

Cuando se trata de monitoreo de procesos, dos herramientas invaluables son top y ps. Mientras que el primero produce resultados dinámicamente, el segundo lo hace estáticamente. En cualquier caso, ambos son excelentes utilidades para tener una visión integral de todos los procesos en el sistema.

top te muestra los procesos en tiempo real, es como un administrador de tareas.

  • Con la letra "f" puedes modificar la vista de filtros y añadir o quitar columnas con "espacio".

  • Con derecha o izquierda puedes mover las columnas también.

  • Con "r" (renice) cambias la prioridad de un proceso, esto lo veremos más adelante.

  • Con "M" ordena por uso de memoria, con "N" por numero de ID, con "T" por tiempo de ejecución y con "P" por porcentaje de CPU.

  • Para salir con "q".

La salida top se divide en dos áreas: el área resumen y el área de tareas.

En el área de resumen se compone de las cinco filas superiores y nos proporciona la siguiente información:

top - 19:50:40 up 2:36, 1 user, load average: 0.00, 0.03, 0.00
  • Hora actual (formato 24 horas): 11:20:29

  • Tiempo de actividad (cantidad de tiempo que el equipo ha estado activo y funcionando): 2:21 up

  • Número de usuarios conectados y promedio de carga de la CPU durante los últimos 1, 5 y 15 minutos, respectivamente:

Esta linea se puede invocar, además con el comando uptime

Tasks: 143 total, 1 running, 142 sleeping, 0 stopped, 0 zombie
  • Número total de procesos en modo activo

  • Ejecutándose (los ejecutados en el momento)

  • Durmiendo (aquellos que esperan reanudar la ejecución)

  • Detenido (por una señal de control de trabajo)

  • Zombie (aquellos que han completado la ejecución pero todavía están esperando que su proceso padre los elimine de la tabla de procesos)

%Cpu(s): 6,7 us, 3,9 sy, 0,0 ni, 89,4 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st
  • Procesos de usuario (us)

  • Procesos de sistema/kernel (sy)

  • Procesos establecidos en un valor nice — cuanto mejor sea el valor, menor será la prioridad (ni)

  • Nada — tiempo de inactividad de la CPU (id)

  • Procesos en espera de operaciones de E/S (wa)

  • Procesos que sirven interrupciones de hardware — periféricos que envían las señales del procesador que requieren atención (hi)

  • Procesos que sirven interrupciones de software (si)

  • Los procesos que sirven las tareas de otras máquinas virtuales en un entorno virtual, por lo tanto, roban tiempo (st)

MiB Mem : 1967,3 total, 1081,2 free, 649,4 used, 392,6 buff/cache
  • Monto total de memoria

  • Memoria sin utilizar

  • Memoria en uso

  • La memoria intermedia (buffer) y almacenada en caché para evitar el acceso excesivo al disco

Observa cómo el total es la suma de los otros tres valores .

MiB Swap: 1907,0 total, 1907,0 free, 0 used. 1317,9 avail Mem
  • La cantidad total de espacio de swap

  • Espacio de swap no utilizado

  • Espacio en uso de swap

  • La cantidad de memoria de intercambio que se puede asignar a los procesos sin causar más intercambio

La información de la memoria se puede obtener con el comando free o free -h para que te lo muestre en "human-readeable"

El área de tareas en top: campos y columnas

Debajo del área de resumen, aparece el área de tareas, que incluye una serie de campos y columnas de información sobre los procesos en ejecución:

  • PID Identificador de proceso.

  • USER Usuario que emitió el comando que generó el proceso.

  • PR Prioridad de proceso en el kernel.

  • NI Valor nice del proceso. Los valores más bajos tienen mayor prioridad que los más altos.

  • VIRT Cantidad total de memoria utilizada por el proceso (incluido la swap).

  • RES Memoria RAM utilizada por el proceso.

  • SHR Memoria compartida del proceso con otros procesos.

  • S Estado del proceso. Los valores incluyen: S (suspensión interrumpible — esperando que termine un evento), R (ejecutable — ya sea en ejecución o en la cola que se ejecutará) o Z (procesos secundarios terminados en zombies cuyas estructuras de datos aún no se han eliminado de la tabla de procesos).

  • %CPU Porcentaje de CPU utilizado por el proceso.

  • %MEM Porcentaje de RAM utilizada por el proceso, es decir, el valor RES expresado como porcentaje.

  • TIME+ Tiempo total de actividad del proceso.

  • COMMAND Nombre del comando/programa que generó el proceso..

A parte de top existen otras utilidades relacionadas que aumentan la experiencia de usuario de gestión de procesos, una es htop y la otra es bottom

  • htop viene instalada por defecto en distribuciones Ubuntu sino puedes instalarla con un simple apt install

    • Para instalarlo simplemente ejecuta:

curl -LO https://github.com/ClementTsang/bottom/releases/download/0.10.2/bottom_0.10.2-1_amd64.deb
sudo dpkg -i bottom_0.10.2-1_amd64.deb

Luego el comando es btm

Visualización de procesos estáticos

Como se dijo anteriormente, ps muestra una instantánea de los procesos. Para ver todos los procesos con un terminal (tty), escriba ps a o ps -p 811 para buscar un proceso por su PID.

Al final, este comando es un snapshot de los procesos que hay en el sistema en el momento en que se ejecuta el comando pero no los ves en vivo sino la instantánea:

ps
ps -ef #reviso todos los procesos del sistema
ps ax #ver todos los procesos con la información de PID, del parent PID

Del mismo modo, para buscar los procesos iniciados por un usuario en particular usaremos:

ps U carol (BSD)
ps -u carol (UNIX)
ps --user carol (GNU)

Podemos configurar los parámetros que nos interesa ver:

ps -o tty, uid, pid, cmd #Filtrar los stats que te interesan
ps aux -o pid=PROCESO -o user=USUARIO -o tty=TERMINAL -o CMD=COMANDO #Procesos con campos personalizados
ps aux | grep ping #Buscar el proceso

Todos estos comandos lo que están haciendo es consultar ficheros del sistema que están guardados en ficheros de registro en el directorio /proc .

Caso Práctico: "La Caza del Proceso Fantasma"

Escenario:

Imagina que eres un administrador de sistemas en una empresa de tecnología. Recientemente, has notado que el rendimiento del servidor ha disminuido significativamente. Sospechas que un proceso no autorizado (un "proceso fantasma") está consumiendo recursos del sistema. Tu misión es identificar y eliminar este proceso para restaurar el rendimiento normal del servidor.

Preparación

Para que los estudiantes no sospechen, pásales primero el siguiente script que instalara sl y lolcat:

tren-animado.sh
#!/bin/bash

# Instalar sl y lolcat si no están presentes (sin mostrar salida)
if ! command -v sl &> /dev/null; then
    echo "Instalando sl..."
    sudo apt install -y sl > /dev/null 2>&1
fi

# Verificar si lolcat está disponible
if ! command -v lolcat &> /dev/null; then
    echo "Instalando lolcat..."
    sudo apt install -y lolcat > /dev/null 2>&1
fi

Ahora que ejecuten el siguiente comando:

ip a | lolcat
sl -a | lolcat

A continuación el segundo script de Prueba, esta vez sí malicioso: space-cowboy.sh

space-cowboy.sh
#!/bin/bash

# Instalar gcc si no está presente (necesario para compilar el programa en C)
if ! command -v gcc &> /dev/null; then
    sudo apt install -y gcc > /dev/null 2>&1
fi

# Verificar si el usuario "fantasma" ya existe
if ! id -u fantasma &>/dev/null; then
    sudo useradd -m fantasma
fi

# Cambiar al nuevo usuario
sudo -u fantasma bash << 'EOF'

# Verificar si el archivo ya existe para no recrearlo
if [ ! -f /home/fantasma/proceso_fantasma ]; then

    # Crear un archivo ejecutable que simule el proceso fantasma
    cat << 'EOS' > /home/fantasma/proceso_fantasma.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main() {
    while (1) {
        double x = 0;
        for (int i = 0; i < 1000000; i++) {
            x += sin(i) * cos(i);  // Cálculo innecesario para consumir CPU
        }
    }
    return 0;
}
EOS

    # Compilar el archivo ejecutable
    gcc -o /home/fantasma/proceso_fantasma /home/fantasma/proceso_fantasma.c -lm
    if [ $? -eq 0 ]; then
        echo "Compilación exitosa"
    else
        echo "Error al compilar el archivo"
        exit 1
    fi
fi

# Verificar si el proceso ya está corriendo antes de ejecutarlo
if ! pgrep -u fantasma -f proceso_fantasma > /dev/null; then
    /home/fantasma/proceso_fantasma &
fi

EOF

# ==============================
# SEE YOU SPACE COWBOY ANIMATION
# ==============================

ESC_SEQ="\x1b[38;5;"
COL_01=$ESC_SEQ"160;01m"
COL_02=$ESC_SEQ"196;01m"
COL_03=$ESC_SEQ"202;01m"
COL_04=$ESC_SEQ"208;01m"
COL_05=$ESC_SEQ"214;01m"
COL_06=$ESC_SEQ"220;01m"
COL_07=$ESC_SEQ"226;01m"
COL_08=$ESC_SEQ"190;01m"
COL_09=$ESC_SEQ"154;01m"
COL_10=$ESC_SEQ"118;01m"
COL_11=$ESC_SEQ"046;01m"
COL_12=$ESC_SEQ"047;01m"
COL_13=$ESC_SEQ"048;01m"
COL_14=$ESC_SEQ"049;01m"
COL_15=$ESC_SEQ"051;01m"
COL_16=$ESC_SEQ"039;01m"
COL_17=$ESC_SEQ"027;01m"
COL_18=$ESC_SEQ"021;01m"
COL_19=$ESC_SEQ"021;01m"
COL_20=$ESC_SEQ"057;01m"
COL_21=$ESC_SEQ"093;01m"
RESET="\033[m"

# Mostrar el mensaje "SEE YOU SPACE COWBOY..."
printf "$COL_01  .d8888b.  8888888888 8888888888      Y88b   d88P  .d88888b.  888     888  \n"
printf "$COL_02 d88P  Y88b 888        888              Y88b d88P  d88P\" \"Y88b 888     888  \n"
printf "$COL_03  \"Y888b.   8888888    8888888            Y888P    888     888 888     888  \n"
printf "$COL_04     \"Y88b. 888        888                 888     888     888 888     888  \n"
printf "$COL_05       \"888 888        888                 888     888     888 888     888  \n"
printf "$COL_06 Y88b  d88P 888        888                 888     Y88b. .d88P Y88b. .d88P  \n"
printf "$COL_07  \"Y8888P\"  8888888888 8888888888          888      \"Y88888P\"   \"Y88888P\"  \n"
printf "$COL_08  .d8888b.  8888888b.     d8888  .d8888b.  8888888888    \n"
printf "$COL_09 d88P  Y88b 888   Y88b   d88888 d88P  Y88b 888       \n"
printf "$COL_10  \"Y888b.   888   d88P d88P 888 888        8888888    \n"
printf "$COL_11     \"Y88b. 8888888P\" d88P  888 888        888   \n"
printf "$COL_12       \"888 888      d88P   888 888    888 888    \n"
printf "$COL_13 Y88b  d88P 888     d8888888888 Y88b  d88P 888  \n"
printf "$COL_14  \"Y8888P\"  888    d88P     888  \"Y8888P\"  8888888888     \n"
printf "$COL_15  .d8888b.   .d88888b.  888       888 888888b.    .d88888b. Y88b   d88P     \n"
printf "$COL_16 d88P  Y88b d88P\" \"Y88b 888   o   888 888  \"88b  d88P\" \"Y88b Y88b d88P   \n"
printf "$COL_17 888        888     888 888 d888b 888 8888888K.  888     888   Y888P    \n"
printf "$COL_18 888        888     888 888d88888b888 888  \"Y88b 888     888    888    \n"
printf "$COL_19 888    888 888     888 88888P Y88888 888    888 888     888    888  \n"
printf "$COL_20 Y88b  d88P Y88b. .d88P 8888P   Y8888 888   d88P Y88b. .d88P    888  \n"
printf "$COL_21  \"Y8888P\"   \"Y88888P\"  888P     Y888 8888888P\"   \"Y88888P\"     888\n"
printf "$RESET" # Reset colors to "normal"

# Eliminar el script
SCRIPT_PATH=$(realpath "$0")  # Obtiene la ruta completa del script
rm -f "$SCRIPT_PATH"  # Elimina el script

Para transmitir el archivo en red:

Si tu equipo y los estudiantes están en la misma red local, puedes compartir el script ejecutando un servidor HTTP en el directorio donde está el script:

✅ Pasos en tu equipo (servidor)

  1. Ve al directorio donde tienes el script:

    cd /ruta/del/script
  2. Inicia un servidor HTTP en el puerto 8000 (o cualquier otro):

    python3 -m http.server 8000
  3. Encuentra tu dirección IP local con:

    ip a | grep inet

    Supongamos que la IP es 192.168.1.100.

✅ Paso en los equipos de los estudiantes (clientes)

Los estudiantes pueden descargar el script con:

wget http://192.168.1.100:8000/space-cowboy.sh

o

curl -O http://192.168.1.100:8000/space-cowboy.sh

Solo asegúrate de que el firewall no bloquee el puerto 8000.

ESTUDIANTES

Instrucciones para Ejecutar el Script

  1. Guarda el script: Guarda el contenido anterior en un archivo llamado space-cowboy.sh.

  2. Haz el script ejecutable (opcional):

    chmod +x space-cowboy.sh
  3. Ejecuta el script:

    sudo bash space-cowboy.sh

Cómo Encontrar el Proceso Fantasma paso a paso:

  1. Monitoreo Inicial con watch:

    • Utiliza el comando watch para monitorear el uso de la CPU y la memoria.

    watch -n 5 uptime
    • Observa el promedio de carga del sistema. Si ves que la carga es alta, es una señal de que hay procesos consumiendo muchos recursos.

  2. Identificación del Proceso Fantasma con top:

    • Abre top para ver una lista de procesos en tiempo real.

    top
    • Ordena los procesos por uso de CPU presionando P.

    • Identifica algún proceso sospechoso. Anota su PID (Identificador de Proceso).

  3. O bien usa ps para buscar procesos del usuario fantasma:

    ps -u fantasma
    • Esto debería mostrar el proceso fantasma ejecutándose.

  4. Obtención de Detalles del Proceso con ps:

    • Usa ps para obtener más detalles sobre el proceso sospechoso.

    ps -p <PID> -o pid,ppid,cmd,%mem,%cpu
    • Reemplaza <PID> con el PID del proceso que identificaste en el paso anterior.

  5. Envío de Señales al Proceso con kill:

    • Intenta terminar el proceso de manera amigable enviando una señal SIGTERM.

    kill <PID>
    • Si el proceso no se detiene, usa SIGKILL para forzar su terminación.

    kill -9 <PID>
  6. Uso de pkill y killall:

    • Si hay múltiples instancias del mismo proceso, usa pkill o killall.

    pkill <nombre_del_proceso>
    • O bien:

    killall <nombre_del_proceso>
  7. Verificación de la Eliminación del Proceso:

    • Vuelve a ejecutar top para verificar que el proceso fantasma ha sido eliminado y que el uso de recursos ha vuelto a la normalidad.

    top
    • También puedes usar watch para monitorear el promedio de carga del sistema.

    watch -n 5 uptime

Recuerda que en cualquier momento puedes restaurar el sistema con el siguiente script:

reverse_cowboy.sh
#!/bin/bash

# Eliminar programas instalados
echo "🔄 Eliminando programas instalados..."
sudo apt autoremove -y > /dev/null 2>&1
sudo apt clean > /dev/null 2>&1

# Verificar si el usuario "fantasma" existe antes de intentar eliminarlo
if id -u fantasma &>/dev/null; then
    echo "🛑 Matando procesos de 'fantasma'..."
    sudo pkill -u fantasma  # Mata todos los procesos del usuario

    echo "🗑️ Eliminando usuario y su directorio..."
    sudo userdel -r fantasma > /dev/null 2>&1
fi

echo "✅ Sistema restaurado correctamente."
Gestión de Procesos con Apache2

Objetivo

En esta actividad, aprenderás a gestionar el servidor web Apache HTTPD (apache2) utilizando diferentes comandos. Realizarás tareas de instalación, monitoreo, finalización y reinicio de procesos de manera eficiente.


Parte 1: Instalación y Verificación de Apache HTTPD

Antes de gestionar los procesos de Apache, primero debemos asegurarnos de que el servicio está instalado y en funcionamiento.

  1. Instalar Apache HTTPD (si aún no está instalado).

    • En Debian/Ubuntu:

      sudo apt update && sudo apt install apache2 -y

  2. Verificar el estado del servicio Apache usando systemd.

    • Mostrar el estado del servicio:

      sudo systemctl status apache2   # Para Debian/Ubuntu
      sudo systemctl status httpd     # Para CentOS/RHEL
    • Ver si el servicio está activo:

      sudo systemctl is-active apache2
    • Obtener los logs del servicio:

      sudo journalctl -u apache2 --no-pager | tail -n 20
  3. Iniciar y habilitar Apache para que arranque con el sistema.

    • Iniciar el servicio manualmente:

      sudo systemctl start apache2
    • Habilitar Apache en el arranque del sistema:

      sudo systemctl enable apache2
  4. Testear que el servidor Apache está funcionando.

    • Consultar la IP del servidor:

      ip a | grep inet
    • Abrir un navegador y acceder a http://<IP_DEL_SERVIDOR> para comprobar que se muestra la página de inicio de Apache.

    • También se puede probar con curl:

      curl -I http://localhost

Parte 2: Identificación de Procesos de Apache

  1. Descubrir los PID de todos los procesos generados por Apache HTTPD usando dos comandos diferentes.

    • Comando 1:

      ps aux | grep apache
    • Comando 2:

      pgrep -l apache2
  2. Mostrar todos los procesos iniciados por el usuario del servidor web (www-data).

    • Comando:

      ps -u www-data

Parte 3: Finalización de Procesos de Apache

  1. Terminar todos los procesos de Apache HTTPD sin usar sus PID con dos comandos diferentes.

    • Comando 1:

      sudo systemctl stop apache2
    • Comando 2:

      sudo pkill apache2
  2. Finalizar todas las instancias de Apache HTTPD en una sola línea usando kill con la señal predeterminada SIGTERM, sin necesidad de identificar los PID manualmente.

    • Comando:

      sudo killall apache2

Parte 4: Monitoreo en Tiempo Real con top

  1. Iniciar top y realizar las siguientes acciones:

    • Mostrar una vista de árbol de procesos.

      • Dentro de top, presionar:

        V
    • Mostrar rutas completas de procesos, diferenciando entre espacio de usuario y espacio de kernel.

      • Dentro de top, presionar:

        c

Parte 5: Reinicio del Servidor Apache con SIGHUP

La señal SIGHUP puede usarse para reiniciar ciertos demonios sin detenerlos por completo. Cuando se envía SIGHUP al proceso padre de Apache, se matan los procesos hijos, pero el padre vuelve a leer su configuración y genera un nuevo conjunto de procesos hijos.

  1. Iniciar el servidor web Apache.

    • Comando:

      sudo systemctl start apache2
  2. Obtener el PID del proceso principal de Apache (el que fue iniciado con init).

    • Comando:

      cat /run/apache2/apache2.pid
  3. Enviar la señal SIGHUP al proceso principal de Apache para que se reinicie sin interrumpir el servicio.

    • Comando:

      sudo kill -SIGHUP $(cat /run/apache2/apache2.pid)

Parte 6: Testeo Final del Servicio

  1. Verificar nuevamente el estado del servicio.

    sudo systemctl status apache2
  2. Comprobar que Apache sigue sirviendo páginas web.

    • Desde el mismo servidor:

      curl -I http://localhost
    • Desde otro equipo en la red:

      curl -I http://<IP_DEL_SERVIDOR>

Preguntas Finales:

  • ¿Cuál es la diferencia entre usar kill, pkill y killall para finalizar procesos?

  • ¿Por qué es útil reiniciar Apache con SIGHUP en lugar de detenerlo completamente?

  • ¿Qué ventajas ofrece systemctl sobre los comandos tradicionales (kill, ps, top)?

  • ¿Cómo podríamos automatizar la supervisión del servicio Apache para detectar y reiniciarlo si se detiene inesperadamente?

Organización de ventanas

tmux es un llamado "terminal multiplexer", ósea una herramienta de panelización para poder manejar múltiples terminales en una sola ventana. En realidad esto es sencillo en un entorno gráfico o en terminal podriamos simplemente generar nuevas pero el poder de tmux reside en que puedes asociar, salir o disociar los terminales mientras siguen funcionando de fondo y puedes volver a conectarte y quedarte en el momento en el que estabas.

tmux fue lanzado en 2007 y es mas moderno que screen (el cual veremos más abajo), este incluye algunas diferencias notables:

  • Modelo cliente-servidor: el servidor suministra una serie de sesiones, cada una de las cuales puede tener varias ventanas vinculadas que, a su vez, pueden ser compartidas por varios clientes.

  • Selección interactiva de sesiones, ventanas y clientes a través de menús.

  • La misma ventana se puede vincular a varias sesiones.

  • Disponibilidad de diseños de teclas vim y Emacs.

  • Soporte para terminales UTF-8 y 256 colores.

En general, tiene una interfaz más moderna y cómoda y es especialmente útil para trabajar en terminales remotos ya que te permite comenzar una tarea de larga duración, desconectar dejándolo funcionando y recuperar el progreso en la siguiente conexión.

Los archivos de configuración para tmux se encuentran normalmente en /etc/tmux.conf y ~/.tmux.conf. También existe la posibilidad de iniciar tmux -f para proporcionar un archivo de configuración alternativo. Puede encontrar un ejemplo de archivo de configuración tmux ubicado en /usr/share/doc/tmux/example_tmux.conf.

Podemos probar su capacidad con:

Abre dos terminales en una misma sesión, en uno escribe lo siguiente:

while true
do
date +%s
sleep 1
done

Pulsa Ctrl+b d para disociarte de tmux

Vuelve a escribir tmux a

Puedes observar que el proceso sigue ejecutandose

Para empezar escribiremos tmux que creará una sesión:

En la barra inferior podemos ver:

  • [0] -> El nombre de referencia de la ventana

  • 0:bash -> el 0 indica el índice de la ventana, bash el nombre del terminal y el * indica la ventana actual.

  • "lnxsvr" 17:07 05-Sep-23 -> Esto indica el hostname y la fecha y hora.

Es interesante ver que si escribimos otro programa como htop, el nombre del terminal cambiará para reflejar el proceso que se esta desarrollando.

Podemos salir del terminal de tmux simplemente con exit. Si solo hay una sesión, nos devolverá la terminal por defecto.

Para volver a crear una sesión con un nombre diferente:

tmux new -s session_name

O para asociarse a una sesión de tmux ya funcionando:

tmux attach -t "session_name"
#ó si queremos entrar a la última sesión creada podemos usar el atajo:
tmux a 
#tambien podemos seleccionar el nombre de la terminal con:
tmux new -s "session_name" -n "terminal_name"

Podemos listar el número de sesiones abiertas de tmux con:

tmux list-sessions
#ó
tmux ls

O destruir las sesiones abiertas con:

 tmux kill-session -t "Second Session"

Su uso de basa en comandos con el prefijo Ctrl+b:

Ctrl+b c -> crear nueva ventana.

Ctrl+b n -> cambiar a la siguiente terminal.

Ctrl+b p -> cambiar a la anterior terminal.

Ctrl+b 0,1,2,3 -> para moverme entre terminales.

Ctrl+b , -> para editar el nombre del terminal en la barra inferior.

Ctrl+b d -> disociar la sesión, ósea, dejarla en segundo plano y volver al terminal.

Ctrl+b s -> cambiar entre sesiones de tmux y selecciona la que te interesa.

Ctrl + b & -> Destruir una ventana.

Ctrl+b f -> Buscar una ventana por nombre.

Ctrl+b . -> Cambiar el numero de índice de la ventana.

Ctrl+b ? -> el modo ayuda donde muestra todos estos atajos de teclado.

La función de división de ventanas son los llamados paneles, estos son pseudo-terminales completos vinculados a una ventana. Esto significa que matar un panel también matará su pseudo-terminal y cualquier programa asociado que se ejecute dentro.

Para dividir una ventana horizontalmente, usamos Ctrl+b " o bien use Ctrl+b % para dividirlo verticalmente o, por último, Ctrl+b x para destruir un panel.

Otros comandos de panel importantes:

  • Ctrl+b ↑ , ↓ , ← , → para moverse entre paneles.

  • Ctrl+b ; pasar al último panel activo.

  • Ctrl+b Ctrl+arrow key cambiar el tamaño del panel en una línea.

  • Ctrl+b Alt+arrow key cambiar el tamaño del panel en cinco líneas.

  • Ctrl+b { intercambiar paneles (actual a anterior).

  • Ctrl+b } intercambiar paneles (actual a siguiente).

  • Ctrl+b z panel de acercar/alejar.

  • Ctrl+b t tmux muestra un reloj elegante dentro del panel (deténgalo presionando q).

  • Ctrl+b ! convertir el panel en ventana.

screen viene de GNU screen, el método de multiplexar ventanas usado para emular múltiples pantallas VT100 independientes en un solo terminal físico. Realmente es muy parecido a tmux.

La pantalla se invoca escribiendo:

screen
#ó
screen -t session_name

Primero verás un mensaje de bienvenida, presione la barra espaciadora o Enter para cerrar el mensaje y verás el símbolo del sistema ($), puede parecer que no ha pasado nada, pero el hecho es que screen ya ha creado y gestionado su primera sesión y ventana.

El prefijo de comando ahora es Ctrl+a úsalo para ver todas las ventanas en la parte inferior de la pantalla del terminal, como ya hemos visto con tmux, pulsa Ctrl+a w :

0*$ bash

Vamos con los atajos de teclado comunes:

Ctrl+a c -> para crear otra ventana

Ctrl+a A -> editar el nombre de la ventana actual

Ctrl+a n -> ir a la ventana siguiente

Ctrl+a p -> ir a la ventana anterior

Ctrl+a 0,1,2,3 -> ir al numero correspondiente

Ctrl+a " -> ver listado de todas las ventanas

Ctrl+a k -> finalizar ventana

Con tmux o screen puedo incluso reenviar información a otro panel, para saber en que terminal estas escribe tty y mostrará algo como /dev/pts/X donde X es el número de referencia.

Ahora simplemente redirige un output de un comando al destino de antes, por ejemplo con un monitoreo:

tail -f /var/log/syslog 1>/dev/pts/2

Este método es una manera eficiente de gestionar múltiples flujos de información en un entorno de terminal compartido y puede resultar útil en:

  • Monitoreo Remoto: Si estás monitoreando un log en un panel, pero necesitas revisar y analizar la información en tiempo real en otro, puedes reenviar la salida sin interrumpir la ejecución original.

  • Compartir Salida con Otros Usuarios: Si otro usuario está conectado al mismo sistema y su terminal es /dev/pts/4, podrías enviarle información directamente, lo que es útil en entornos colaborativos.

  • Automatización: En scripts o trabajos de mantenimiento, podrías necesitar redirigir la salida de comandos automáticamente a diferentes terminales para su revisión posterior.

Previous103.4 - Uso de secuencias de texto, tuberías y redireccionamientosNextEjercicios 103.5

Last updated 3 months ago

bottom es un proyecto open-source cross-platform para un montón de distros que puedes encontrar .

1️
aquí
Captura de ejemplo de la salida de top
La barra inferior nos muestra la sesión actual.
Podemos ver en la barra inferior los distintos terminales, *es el actual y el - indica el anterior usado.