#!/bin/bash ############################################################################ # Script para control de procesos. # # El script solicitará un nombre de proceso y mostrará cuatro posibles # opciones: Ver información del proceso; editar su prioridad; detenerlo # o relanzarlo; y finalizar su ejecución. # # Autor: angeldp # ############################################################################ clear # Las variables CTR y OPC las usaré para salir de los bucles. CTR=0 OPC=0 # Pediré que introduzca el nombre de un proceso hasta que se indique # uno que exista y que sólo haya un con ese nombre. Para ayudar, # muestro la lista de procesos en ejecución propiedad del usuario # que ejecuta el script (LPROCESOS) LPROCESOS=`ps ux | grep ^$USER | tr -s ' ' | cut -d " " -f11 | grep -v ^/` until [ $CTR -eq 1 ] do clear echo "Indique un proceso de los siguientes:" echo "$LPROCESOS" read PROCESO CTR=`ps ux | grep ^$USER | tr -s ' ' | cut -d " " -f11 | grep $PROCESO | wc -l` # Si no se encuentra ningún proceso lo indico antes de pedirlo de nuevo. if [ $CTR -eq 0 ] then echo "No se ha encontrado ningún proceso de $USER llamado $PROCESO" echo "Pulse cualquier tecla para volver a intentarlo." read -n1 -s NADA # si hay más de un proceso con ese nombre, muestro un mensaje advirtiéndolo. elif [ $CTR -gt 1 ] then echo "Se ha encontrado más de un proceso de $USER llamado $PROCESO" echo "Pulse cualquier tecla para volver a intentarlo." read -n1 -s NADA fi done # Fin de until [ $CTR -eq 1 ] # Por medio de este bucle mostraré un menú hasta que no se pulse # la opción de salida del script ( x mayúscula o minúscula. ) until [ "$OPC" = "x" -o "$OPC" = "X" ] do # Dado que voy a necesitar en varias ocasiones valores como el PID, el estado, # la prioridad, etc. Almaceno esos valores en unas variables antes de mostrar el menú: NEWPRI=100 NUMPID=`ps ux | grep ^$USER | tr -s ' ' | cut -d " " -f1-11 | grep $PROCESO | cut -d " " -f2` NUMCPU=`ps ux | grep ^$USER | tr -s ' ' | cut -d " " -f1-11 | grep $PROCESO | cut -d " " -f3` NUMMEM=`ps ux | grep ^$USER | tr -s ' ' | cut -d " " -f1-11 | grep $PROCESO | cut -d " " -f4` PRIOR=`ps lx | tr -s ' ' | cut -d " " -f1-13 | grep $PROCESO | cut -d" " -f6` STADO=`ps ux | grep ^$USER | tr -s ' ' | cut -d " " -f1-11 | grep $PROCESO | cut -d " " -f8` # Dependiendo del primer caracter del campo estado, actualizo # la variable ESTADO a su correspondencia legible case $STADO in D* )ESTADO="bloqueado";; R* )ESTADO="ejecutándose";; S* )ESTADO="dormido";; T* )ESTADO="detenido";; Z* )ESTADO="zombie";; * ) ESTADO="desconocido";; esac clear echo "M ---> Muestra información detallada del proceso $PROCESO" echo "C ---> Permite modificar la prioridad de $PROCESO" echo "D ---> Se emplea para detener o relanzar el proceso" echo "K ---> Intentará finalizar la ejecución del proceso $PROCESO" echo "X ---> Salir" # Leo un solo caracter (-n 1) en OPC e impido que se muestre (-s) read -n1 -s OPC # Dependiendo del carácter almacenado en OPC... case $OPC in # Si se pulsó una "M" mayúscula o minúscula muestro la información "m"|"M" ) clear echo "El PID del proceso $PROCESO es $NUMPID." echo "Su porcentaje de uso de procesador: $NUMCPU%" echo "Su porcentaje de uso de memoria es: $NUMMEM%" echo "Se está ejecutando con prioridad $PRIOR" echo "$PROCESO se encuentra en estado $ESTADO" echo "" echo "Pulse cualquier tecla para volver al menú. " read -n1 -s NADA;; # Si se pulsó C modifico la prioridad "c"|"C" ) clear # Si el usuario es root, permito valores entre 19 y -20 if [ "$USER" = "root" ] then until [ $NEWPRI -le 19 -a $NEWPRI -ge -20 ] do clear echo "La prioridad actual de $PROCESO es $PRIOR," echo -n "indique una nueva entre 19 (menor) y -20 (mayor): " read NEWPRI done else # si no es root, los valores permitidos están entre 0 y 19 until [ $NEWPRI -le 19 -a $NEWPRI -ge 0 ] do clear echo "La prioridad es $PRIOR, indique una nueva entre 0 (mayor) y 19 (menor)" read NEWPRI done fi # Con la prioridad en el rango permitido, la cambio: renice -n $NEWPRI -p $NUMPID > /dev/null 2>&1 echo "La nueva prioridad es: `ps lx | tr -s ' ' | cut -d " " -f1-13 | grep $PROCESO | cut -d" " -f6`" echo "Pulse cualquier tecla para volver al menú. " read -n1 -s NADA;; # Si se pulsó K se finalizará el proceso "k"|"K" ) clear echo "Intentando acabar con $PROCESO" # Primero se intenta por las buenas enviando SIGTERM kill -15 $NUMPID >/dev/null 2>&1 # si el proceso continua en ejecución se envía SIGKILL if [ `ps ux | grep ^$USER | tr -s ' ' | cut -d " " -f11 | grep $PROCESO | wc -l` -ne 0 ] then kill -9 $NUMPID >/dev/null 2>&1 # si aún está ejecutándose (cosa poco probable) se advierte. if [ `ps ux | grep ^$USER | tr -s ' ' | cut -d " " -f11 | grep $PROCESO | wc -l` -ne 0 ] then echo "Ha sido imposible acabar con $PROCESO, " echo "inténtelo de nuevo más tarde. " else echo "El proceso ha sido eliminado." # Coloco la opción x en OPC para salir del menú # ya que no existe más el proceso OPC="x" fi else echo "El proceso ha finalizado" # Y pongo X en OPC para que no vuelva a salir el menú OPC="x" fi echo "Pulse cualquier tecla para finalizar. " read -n1 -s NADA;; # Si la opción ha sido la D habrá que detener el # proceso (si está ejecutándose) o relanzarlo # si está detenido. En otro caso no se hará nada. "d"|"D" ) clear echo "El proceso $PROCESO se encuentra $ESTADO" if [ "$ESTADO" = "ejecutándose" -o "$ESTADO" = "dormido" ] then echo "Deteniendo $PROCESO" kill -s SIGSTOP $NUMPID > /dev/null 2>&1 elif [ "$ESTADO" = "detenido" ] then echo "Relanzando $PROCESO" kill -s SIGCONT $NUMPID > /dev/null 2>&1 else echo "No se hará nada" fi echo "Pulse cualquier tecla para volver al menú. " read -n1 -s NADA;; # Si la opción pulsada es la x limpio la pantalla y finaliza el script "x"|"X" )clear;; # Si ha pulsado cualquier otra cosa hay que advertir del error. * ) clear echo "Opción inválida: $OPC" echo "Pulse cualquier tecla para regresar al menú." read -n1 -s NADA;; esac # Fin del menú done # Fin del bucle until [ "$OPC" = "x" -o "$OPC" = "X" ]