En multitud de ocasiones, mientras estamos trabajando con nuestro ordenador, o incluso con un servidor remoto, se presenta la necesidad de saber la memoria ocupada o la CPU consumida por un determinado proceso.
Para ello tenemos herramientas como top o ps (entre otras) que nos permiten conocer dicha información. Podemos encontrar multitud de tutoriales para ambos comandos, sólo daré una pincelada aquí.
ps
Casi siempre que uso ps suelo hacerlo de la siguiente manera:
$ ps ax
para así mostrar todos los procesos que están corriendo actualmente, y si queremos obtener información sobre memoria y CPU podremos ejecutar:
$ ps axl
o
$ ps axo pid,pcpu,pmem,size,cmd
Si queremos obtener más datos como ID de proceso (pid), % de CPU (pcpu), % de memoria (pmem), tamaño en memoria (size), comando que genera el proceso (cmd).
top
Desde aquí podemos ver en tiempo real los procesos que están ejecutándose en la máquina (se va actualizando en el tiempo) y podemos ordenarlos por varios criterios pulsando (<) y (>) además de filtrarlos, matarlos, etc. Para salir, debemos pulsar q.
Otros administradores
Por supuesto, también tenemos administradores gráficos de tareas, por ejemplo, aquí tenemos un pantallazo del administrador de tareas de KDE:
Con muchas opciones.
Agrupando procesos
Pero en la vida del sysadmin, en ocasiones tenemos la necesidad de saber lo que ocupan todos los procesos con el mismo nombre. Porque, muchas veces, un mismo programa lanza varios procesos homónimos que corren de forma concurrente. Podemos verlo, por ejemplo, cuando ejecutamos Chrome o Chromium, Spotify, procesos de Apache, PHP, o incluso cuando tenemos muchas sesiones de terminal abiertas y queremos saber cuánta memoria ocupan todas juntas.
Para eso, podemos utilizar el siguiente script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | #!/bin/bash GROUP_ARG=$1 HUMAN=0 case $GROUP_ARG in "rss") GROUPABLE="rss" HUMAN=1 ;; "size") GROUPABLE="size" HUMAN=1 ;; "pmem") GROUPABLE="pmem" HUMAN=0 ;; "pcpu") GROUPABLE="pcpu" HUMAN=0 ;; *) echo "Bad argument!" exit esac ps -axo pid,$GROUPABLE,cmd | awk ' function human(x) { s="KiB MiB GiB TiB EiB PiB" while (x>=1024 && length(s)>1) { x/=1024; s=substr(s,5) } s=substr(s,0,3) return sprintf( "%.2f%s", x, s) } BEGIN { i=0 } { if (!procesos[$3]) { procesos[$3]=i pids[i]=$1 "" group[i]=$2 i++ } else { n = procesos[$3] pids[n]=pids[n] ", " $1 "" group[n]+=$2 } } END { for (p in procesos) { i = procesos[p]; if ('$HUMAN') printf "%s %s (%s)\n", p, human(group[i]), pids[i] else printf "%s %s (%s)\n", p, group[i], pids[i] } } '; |
Cuando lo ejecutemos, debemos pasar un argumento: rss (tamaño de la parte residente en memoria del proceso), size (tamaño virtual del programa), pmem (% de memoria), pcpu (% de CPU) dependiendo del criterio que vamos a agrupar.
Si observamos, el script hace una llamada a ps -axo pid,(parametro),cmd por lo que recibiremos sólo 3 elementos de cada proceso, su identificador, el elemento que queremos agrupar y la línea de comandos invocada para correr el proceso. Todo eso se lo pasamos a awk que procesará línea por línea dicha información.
Dentro de awk, tenemos la función human, que transformará tamaños de KiB a unidades superiores (para que los tamaños sean más fáciles de leer, por ejemplo 1048576KiB = 1GiB). Awk, manejará 3 arrays, procesos, pids y group. Procesos[] asignará a cada cmd un índice consecutivo. pids[] asignará a cada índice una lista de IDs de procesos separados por comas, al final será una cadena de texto y group[] asignará a cada índice un número que será la suma de todos los argumentos que agrupemos (ya sabemos, memoria, cpu…). Lo que awk hará en cada iteración será buscar si ya ha visto un proceso con ese nombre, en caso afirmativo añadirá la información de la línea actual a los arrays del proceso, de otro modo, añadirá un elemento a cada array con información del proceso que acabamos de ver.
Para finalizar, una vez se haya recopilado la información, se recorrerá el array de procesos para imprimir en pantalla la información formateada y, en el caso de que la información a agrupar sea un tamaño (memoria), lo pondremos en formato humano (función human de arriba) para facilitar la legibilidad.
Ejemplos de uso
Yo he llamado al programa groupps. Para ejecutarlo puedo hacer:
$ ./groups size
y me mostrará el espacio ocupado por todos los procesos. Aunque podemos usar grep para filtrar esta información, por ejemplo, para ver cuánto ocupan todos los procesos de php-cgi-5.5 que tengo actualmente corriendo:
$ ./groups size | grep php-cgi-5.5
/opt/phpfarm/inst/bin/php-cgi-5.5.19 101.23MiB (4790, 4791, 4792, 4793, 4846, 4847, 4848, 4849, 4850, 4851, 4852, 4853, 28576, 28640, 28641, 28642)
En este caso veo que la suma del tamaño de todos los procesos de php es de 101.23MiB. Tenemos que tener
O puedo ver la CPU total consumida por los procesos de Spotify:
$ ./groupps pmem | grep spotify
/usr/share/spotify/spotify 12.3 (31847, 31849, 31863, 31879)
En este caso un 12.3%
Sobre este script
Este script lo incluiré en gscripts muy pronto, junto con una colección de scripts para hacer nuestra vida con la terminal más fácil.
Foto: Hoach Le Dihn
The post Cómo conocer CPU y memoria ocupada por un grupo de procesos con el mismo nombre appeared first on Poesía Binaria.