Cada vez que ejecutamos una aplicación, como mínimo, estará corriendo un proceso en el sistema operativo que realiza las funciones programadas en esa aplicación o que le estamos ordenando desde la interfaz de usuario.
Dentro de la estructura de ejecución de un proceso hay tres elementos importantes que debemos conocer:
- PID (Process ID): Es un identificador numérico único para cada proceso.
- PPID (Process Parent ID): El identificador del proceso padre.
- UID (User ID): Identificador único del usuario propietario del proceso.
- GID (Group ID): Identificador del grupo propietario del proceso.
Los sistemas Linux están pensados para ser multitarea, multihilo y multiusuario para aprovechar al máximo la tecnología de los procesadores actuales. Esto significa que podemos ejecutar más de un proceso al mismo tiempo, utilizando más de un núcleo del procesador y por diferentes usuarios.
A continuación, voy a explicar algunos de los comandos más básicos de Linux para tratar con los procesos.
Mirar qué procesos están corriendo
Utilizaremos el comando ps y sus diferentes parámetros, según lo que queramos mirar. Si ejecutamos «man ps» veremos para qué sirve cada parámetro.
- Mirar todos los procesos que se están ejecutando en el sistema: ps -ef
- Mirar todos los procesos que está ejecutando un usuario: ps -fu usuario
- Filtrar algunas de las columnas de ps: ps -eopid,tt,user,fname,tmout,f,wchan
Ejemplo:
# ps -flU usuario1
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
4 S usuario1 5083 5082 0 80 0 - 22179 wait 11:45 pts/1 00:00:00 -bash
0 R usuario1 5118 5083 0 80 0 - 22134 - 11:45 pts/1 00:00:00 ps -f
#
El significado de cada una de las columnas es:
UID → Propietario del proceso.
PID → ID del proceso.
PPID → ID del proceso padre.
C → Cantidad de recursos de CPU que el proceso ha utilizado recientemente para que el kernel (núcleo del sistema operativo) establezca la prioridad apropiada a cada proceso.
PRI → Prioridad del proceso.
NI → Valor nice. Un valor positivo indica menor tiempo de CPU.
STIME → Hora de comienzo del proceso.
TTY → Terminal asociado al proceso.
TIME → Tiempo de CPU asociado al proceso.
CMD → Comando ejecutado.
Revisar el consumo de CPU y memoria de cada proceso en tiempo real
Utilizaremos el comando «top».
# top
top - 16:52:53 up 21 days, 21:35, 1 user, load average: 0.02, 0.08, 0.08
Tasks: 93 total, 1 running, 92 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1014736 total, 149260 free, 558436 used, 307040 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 205908 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 43248 3128 1952 S 0.0 0.3 0:10.99 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.08 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:05.11 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
7 root rt 0 0 0 0 S 0.0 0.0 0:00.00 migration/0
8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh
9 root 20 0 0 0 0 S 0.0 0.0 2:34.89 rcu_sched
10 root rt 0 0 0 0 S 0.0 0.0 0:08.40 watchdog/0
12 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kdevtmpfs
13 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 netns
14 root 20 0 0 0 0 S 0.0 0.0 0:00.01 xenwatch
15 root 20 0 0 0 0 S 0.0 0.0 0:00.00 xenbus
17 root 20 0 0 0 0 S 0.0 0.0 0:00.30 khungtaskd
18 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 writeback
Para ordenar los procesos que más memoria consumen, utilizaremos el siguiente comando:
# ps -e -o vsz=Kbytes -o ruser -o pid,args=Command-Line | sort -rnk1 | more
644584 puerto53 10013 httpd -f /app/puerto53/httpd/conf/httpd.conf -k start -D SSL
643768 puerto53 19412 httpd -f /app/puerto53/httpd/conf/httpd.conf -k start -D SSL
642648 puerto53 15740 httpd -f /app/puerto53/httpd/conf/httpd.conf -k start -D SSL
640556 puerto53 10937 httpd -f /app/puerto53/httpd/conf/httpd.conf -k start -D SSL
637536 puerto53 21861 httpd -f /app/puerto53/httpd/conf/httpd.conf -k start -D SSL
636416 puerto53 15040 httpd -f /app/puerto53/httpd/conf/httpd.conf -k start -D SSL
634840 puerto53 9998 httpd -f /app/puerto53/httpd/conf/httpd.conf -k start -D SSL
621788 puerto53 21859 httpd -f /app/puerto53/httpd/conf/httpd.conf -k start -D SSL
621072 puerto53 19411 httpd -f /app/puerto53/httpd/conf/httpd.conf -k start -D SSL
607532 puerto53 15467 httpd -f /app/puerto53/httpd/conf/httpd.conf -k start -D SSL
562388 root 810 /usr/bin/python -Es /usr/sbin/tuned -l -P
534132 polkitd 550 /usr/lib/polkit-1/polkitd --no-debug
505752 puerto53 17662 httpd -f /app/puerto53/httpd/conf/httpd.conf -k start -D SSL
263152 root 552 /usr/sbin/rsyslogd -n
201256 root 544 /usr/sbin/gssproxy -D
195584 root 21937 sudo su -
187536 root 21938 su -
151064 root 21956 ps -e -o vsz=Kbytes -o ruser -o pid,args=Command-Line
145700 root 21915 sshd: centos [priv]
145700 centos 21917 sshd: [email protected]/0
126264 root 1015 /usr/sbin/crond -n
118848 root 398 /usr/sbin/lvmetad -f
115640 chrony 539 /usr/sbin/chronyd
Matar un proceso
A veces los procesos tienen algún error y la aplicación no es capaz de finalizar por sí sola. En ese caso, podemos utilizar el comando «kill PID» para matar el proceso relacionado con esa aplicación.
# kill -9 4997
Capturar la señal de finalización de un proceso
Nos puede ser útil para la creación de scripts. Por ejemplo, si el proceso acaba bien haz una tarea pero si acaba mal haces otra cosa.
# cat trap.sh
#!/bin/sh
echo Capturador de señales: trap 'echo señal SIGNINT recibida' 2;
while true
do
:
done
#
# ./trap.sh Capturador de señales:
^Cseñal SIGINT recibida
El mensaje señal SIGINT recibida lo vemos al presionar Control-C (señal 2).
Modificar la prioridad de ejecución de un proceso (nice)
La prioridad de un proceso se mide del uno al 19, siendo el 19 el menos prioritario. Por defecto, un proceso se ejecuta con prioridad 10, pero podemos forzarla o cambiarla:
# nice -7 proceso
# renice -n 20 20699
20699: old priority 4, new priority 20
#
Saber cuánto tiempo tarda en ejecutarse un proceso
El comando «time proceso» mide el tiempo de ejecución de un proceso, mostrando las estadísticas de rendimiento al acabar.
# time ls
anaconda-ks.cfg original-ks.cfg
real 0m0.004s
user 0m0.000s
sys 0m0.001s
[[email protected] ~]#
Lanzar procesos en background
Seguramente nos interesará lanzar procesos en segundo plano cuando la duración del mismo sea elevada como, por ejemplo, un batch de nóminas, o se nos pueda cortar nuestra conexión al terminal por problemas en nuestra red.
Para hacerlo, ejecutaremos:
nohup proceso &
Tras la ejecución de este comando conseguiremos tres cosas:
- El proceso se ejecuta en segundo plano.
- Nos devuelve el prompt del sistema para que sigamos utilizando nuestra terminal.
- Si salimos de la sesión o se nos corta, el proceso seguirá ejecutandose hasta que finalice.
Ejemplo:
# ls > prueba.txt &
[1] 8788
# ps -ef |grep 8788 usuario1 8790 8754 2 10:05 pts/0 00:00:00 grep 8788
[1]+ Done ls --color=auto > prueba.txt
# cat prueba.txt
contactos letras otro_directorio
prueba.txt
#
Planificación de tareas con cron
crond es el demonio (o servicio de sistema que se ejecuta en segundo plano) que se encarga de revisar el fichero de cron de todos los usuarios para ejecutar cada una de las tareas en la fecha y hora programadas.
Este sistema es muy útil para ejecutar tareas periódicamente o, incluso, para no tener que activarlas manualmente a horas indecentes.
Con el comando «crontab -e» editaremos nuestro fichero de configuración de cron, siempre que el administrador del sistema operativo nos lo haya permitido:
[[email protected] ~]# cat /etc/cron.allow
puerto53
[[email protected] ~]#
La sintaxis de cron la podremos consultar con «man crontab» si tenemos alguna duda, pero es realmente sencillo de entender:
minuto hora días mes días_semana comando
Ejemplo:
[[email protected] puerto53]$ crontab -l
# Copias de seguridad del codigo HTML
00 03 1,8 * 1 /app/puerto53/scripts/Backups/backup.sh > /dev/null 2>&1
[[email protected] puerto53]$
Ejecución de varios comandos en la misma línea de cron
Si queremos ejecutar varios comandos de cron en la misma línea, tenemos dos opciones:
- Meter todos los comandos en un script y llamar a ese script desde cron.
- Llamar a un comando detrás de otro, tal y como explico en el post 5 maneras de ejecutar comandos en Linux.
Ejecutar una tarea en cron cada pocos minutos o cada pocos segundos
Si queremos ejecutar tareas, por ejemplo, cada 5 minutos, utilizaremos el separado «/» en el campo donde se indican los minutos. Lo veremos más fácil con un ejemplo:
*/5 * * * * comando
Si esa misma tarea la queremos ejecutar cada 30 segundos, por ejemplo, utilizaremos el comando «sleep» seguido del comando que queremos ejecutar:
* * * * * sleep 30; comando
Configurar variables de entorno en cron
Lo ideal es que los scripts que ejecutamos contengan todas las variables de entorno que necesitan, de lo contrario, es posible que cron no encuentre ciertos comandos incluidos dentro del script.
Aún así, si lo deseamos, podemos configurar variables de cron en el propio cron. Como ejemplo, configuraremos la variable PATH:
PATH=/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin
* * * * * comando