educación, informática y demás

2406 - Procesos

Gestión de procesos

Sabemos que un proceso es un programa en ejecución. El S.O. debe almacenar información de todo proceso que esté ejecutando en el sistema para poder gestionarlo. Para ello se utiliza una estructura de datos en memoria, habitualmente una lista o tabla, dónde se almacena información para cada proceso.

Ten en cuenta que habitualmente tenemos muchos procesos en ejecucion en nuestro sistema operativo, de alguna forma el SO tiene que poder identificar a cada proceso y los recursos que utiliza para poder gestionarlo.

La información que se guarda para un proceso se almacena en una estructura de datos llamada BCP o Bloque de Control de Proceso. Esta estructura de datos guarda información necesaria para gestionar un proceso en el sistema operativo. Entre toda la información que se almacena, cabe destacar:

  • PID. Process Idetificator, es el identificador del proceso. Se trata de un número que identifica el proceso de forma única en el sistema.
  • Binario. El nombre del programa. También se puede almacenar la ruta del programa que se está ejecutando en el proceso.
  • Usuario. El usuario del sistema que ha lanzado el proceso.
  • Estado del proceso. Ejecución, listo, bloqueado E/S, … El estado depende de los algoritmos de planificación utilizados por el planificador del S.O.
  • Recursos. Direcciones de memoria del proceso, ficheros abiertos, etc….
  • ….

GNU/Linux Debian

En nuestro caso estamos trabajando ahora mismo con GNU/Linux Debian 12 con xfce como entorno de escritorio. Vamos a buscar una herramienta gráfica que muestre los procesos en ejecución.

En nuestro caso tenemos instalada la aplicación Gestor de tareas.

¿Como es posible que haya tantos procesos en ejecución si no hemos lanzado ninguna aplicación?. Muchos de estos procesos son servicios del sistema o de alguna parte del mismo. En los sistemas Unix-Like a los servicios se les denomina demonios o daemos, de ahí que el nombre de muchos servicios termine con una d de daemon.

Vamos a ejecutar un programa

El proceso se crea y se lanza

Esperamos y volvemos a comprobar

Podemos configurar qué procesos se mostrarán y qué información de cada proceso se mostrará en las columnas.

Vamos a probar a lanzar una aplicación en segundo plano desde una terminal para comprobar que realmente se crea un proceso con el PID que se muestra en la terminal y que, además, ese proceso forma parte del árbol de procesos del proceso que lo ha ejecutado.

Ahora vamos a detener el proceso padre.

Una vez detenido, cambia la información y no responde al sistema.

Si le damos a continuar

Vamos a ver si tenemos diferencia entre finalizar y matar… Vamos a modificar el fichero para que, cuando tratemos de finalizar, si la aplicación tiene control sobre la señal de finalizar que recibe desde el S.O. nos muestre el típico mensaje de que no se han guardado los cambios.

Si intentamos cerrar la aplicación como usuario recibiremos el siguiente mensaje.

Cancelamos y desde el Gestor de tareas vamos a mandar la señal de finalizar.

Lo hace, se ha cerrado :_(

Al tratar de lanzarlo otra vez nos muestra

Recuperamos lo que teníamos!

Vamos a matarlo ahora.

Ahora si tratamos de volver a lanzarlo…

Comandos de gestión de procesos

  • top
  • ps
  • kill
  • killall
  • xkill

Comando top

Vamos a jugar ahora solo con la terminal.

Nos muestra información de procesos en tiempo real de forma interactiva. Para salir de esta aplicación pulsamos la tecla q de quit.

Este comando lo podemos utilizar para echar un vistazo en tiempo real de los proceso que están en el sistema y la carga que provocan. No obstante, vamos a utilizar más otros comandos que nos permitan a la larga automatizar tareas.

Comando ps

Vamos a jugar un poco con ps.

No está mostrando todos los proceso, para ello podríamos utilizar la opción -A

Vamos a usar ps -A

¿Podrías mostrar las últimos 15 procesos en ejecución?

¿Podrías mostrar los 15 primeros?

Almacena la información de los 15 primeros procesos en un fichero llamado procesos.txt. Si el fichero existe sobrecríbelo.

Repite el comando, pero solo muestra o almacena, el PID y el nombre del proceso.

Hay un espacio delante, podemos quitarlo o pensar que hay un campo vacío.

Lo guardamos en un fichero

Vamos a mostrar más información sobre los procesos

Muestra solo los procesos del usuario alumno.

Determina el número de procesos en ejecución del usuario alumno.

Script infoUserPS.sh

Queremos guardar toda esta información en un fichero, cuyo contenido sea en la primera línea el nombre del usuario, por supuesto con una etiqueta. Es decir, así como «Usuario: alumno»

  • Primera línea nombre del usuario.
  • En la siguiente línea la fecha y hora actual.
  • Después el número de procesos en ejecución para este usuario.
  • A continuación una línea con el nombre de cada uno de los campos que se mostrarán para cada proceso
  • Por último la lista de procesos en ejecución para este usuario.

Vamos a tener que crear un script que llamaremos infoUserPS.sh

Realiza el control de errores oportuno.

findProcess.sh

Vamos a crear otro script que muestre información sobre procesos que estén ejecutando algún comando o aplicación dada. El script recibirá por parámetro el nombre del comando o aplicación que pretendemos buscar.

Primero comprobaremos si dicha aplicación se está ejecutando en el sistema. Si no se está ejecutando, mostraremos un mensaje indicando que no hay ningún proceso en ejecución con ese nombre.

Si hubiera procesos en ejecución, mostraremos el número de procesos en ejecución con ese nombre aproximado, es decir cuyo nombre contenga la cadena de texto pasada por parámetro.

Después mostremos una lista con información de procesos que estén ejecutando el comando seleccionado. Para cada proceso mostraremos:

  • Nombre del usuario que está ejecutando el proceso.
  • PID del proceso.
  • Tanto por ciento de uso de memoria
  • Cuándo se inicio el proceso
  • Tiempo de uso de la CPU
  • Comando utilizado para lanzarlo

Realiza el control de errores oportuno.

Lanzando aplicaciones en segundo plano

Podemos lanzar comandos o aplicaciones desde la terminal. Sin embargo, cuando hacemos esto, el proceso bash se queda detenido hasta que termina de ejecutarse la aplicación.

Podemos lanzar la aplicación en cuestión en segundo plano añadiendo al final de la línea el carácter &. Sin embargo, hay que tener cierto cuidado con esta práctica, puesto que el nuevo proceso creado para lanzar la aplicación en segundo plano no tiene área de visualización propia en la terminal. Si se trata de una aplicación con GUI no hay problema, pero si es una aplicación que necesita entrada de datos desde teclado en la terminal, podemos tener problemas.

Otro problema que suele darse es lanzar un comando como sudo utilizando el & al final. Si es el primer comando con sudo que lanzamos, sudo nos solicitará la contraseña, pero el programa no mostrará nada en pantalla…

Veamos algunos ejemplos de uso

en el segundo caso, la cadena de texto que solicita la contraseña ni se muestra ni puede obtener la entrada de datos del usuario, puesto que el proceso se ha lanzado en segundo plano.

Vamos a buscar el proceso por su PID

Matando procesos

Para matar procesos podemos utilizar varios comandos: kill, killall, pkill o xkill son algunos de ellos.

Vamos a matar el proceso que está a la espera lanzado con sudo

Al utilizar kill sin opciones, el comando kill envía al proceso en cuestión la señal TERM que le indica que termine cuando sea posible.

Si queremos que el proceso se termine si o si, sea o no posible, le tenemos que enviar una señal KILL o -9

Vamos a ver otro comando similar para matar procesos, el comando pkill.

Con killall podemos matar todos los procesos que compartan el mismo nombre.

Con xkill podemos matar el proceso asociado a una ventana

Script killUserProcess.sh

El script debe controlar posibles errores en tiempo de ejecución, por ejemplo, este script debe ser ejecutado por root y es obligatorio que reciba el nombre del usuario por parámetro.

Este script se encargará de matar todos los procesos del usuario pasado por parámetro en el sistema. Si el usuario en cuestión no tiene ningún proceso en el ejecución mostramos un mensaje advirtiendo de la situación y terminamos el script.

Solución propuesta

Script killAll.sh

El script debe controlar posibles errores en tiempo de ejecución, por ejemplo, este script debe ser ejecutado por root y es obligatorio que reciba el patrón de nombre de comando o aplicación a matar por parámetro.

Este script se encargará de matar todos los procesos cuyo nombre coincida parcial o totalmente con el valor pasado por parámetro. Si no hay ningún proceso que contenga dicho patrón mostramos un mensaje advirtiendo de la situación y terminamos el script.

Extra!

Crea un script que reciba por parámetro una lista de nombres de usuario. El script deberá crear un cuenta de usuario nueva con el nombre del usuario pasado por parámetro y como contraseña el nombre del usuario.

addUserList.sh

Ejemplo de uso:

addUserList.sh marinapg alfredoff ramonam soledadgm lolafm

El usuario marinapg ya existe en el sistema

alfredoff creado correctamente

Ayuda

  • La lista de parámetros está en $@. Podemos recorrerla con un for, es más podemos hacerlo sin añadir la parte in $@ puesto que si no escribimos el in por defecto for recorre los parámetros pasados al script o función en la que se encuentre.
  • useradd. Con useradd podemos crear usuarios sin tener que insertar contraseñas.
  • chpasswd. Para usar chpasswd le vamos a pasar a través de una tubería el nombre del usaurio seguido de la contraseña separado por dos puntos. Para ello utilizaremos el comando echo. echo «nombre:nombre» | chpasswd

Solución propuesta

Solución una mijina más controlada

Solución más comprensible

Usando funciones para hacer más comprensible

Solución rápida para un administrador

Solución leyendo de un fichero

Continuamos!!

Vamos a iniciar sesión con varios usuarios. Una vez hecho esto, usando el comando w o who vamos comprobar que realmente hay varios usuario con sesión iniciada en el sistema.

Ahora vamos a matar todos los procesos de marinapg.

Parece que todo va bien, pero…

Resulta que no ha podido matar dos procesos de ramonam… El primer proceso que se ha matado de ramonam posiblemente sería su proceso de inicio de sesión o init. De ese proceso dependen el resto de procesos que lance ramonam, en este caso el proceso bash había lanzado un par de procesos. Al matar al proceso /bin/bash esos procesos también murieron 🙂

Script killAll.sh

El script debe controlar posibles errores en tiempo de ejecución, por ejemplo, este script debe ser ejecutado por root y es obligatorio que reciba el patrón de nombre de comando o aplicación a matar por parámetro.

Este script se encargará de matar todos los procesos cuyo nombre coincida parcial o totalmente con el valor pasado por parámetro. Si no hay ningún proceso que contenga dicho patrón mostramos un mensaje advirtiendo de la situación y terminamos el script.

Código fuente de la solución propuesta

Mejorado usando ps aux

Afinando un poco más 🙂

Dejar una respuesta