¿Cómo puedo solicitar ps
mostrar solo procesos de usuario y no hilos de kernel?
Vea esta pregunta para ver a qué me refiero ...
¿Cómo puedo solicitar ps
mostrar solo procesos de usuario y no hilos de kernel?
Vea esta pregunta para ver a qué me refiero ...
Respuestas:
Esto debería hacer (bajo Linux):
ps --ppid 2 -p 2 --deselect
kthreadd
(PID 2) tiene PPID 0 ( en Linux 2.6+ ) pero ps
no permite filtrar por PPID 0; Por lo tanto, esta solución.
kthreadd
, luego cree la ps
llamada correspondiente. ¿Qué tan seguro está de que esta cosa "siempre" se llame "kthreadd"? Una solución segura sería más complicada, se ejecuta ps
normalmente y analiza la salida, tal vez haga algunas pruebas.
x
bandera que no funciona con esto. ps au --ppid 2 -p 2 --deselect
funciona bien
Una forma de reconocer los procesos del kernel es que no usan memoria de usuario, por lo que el campo vsz es 0. Esto también atrapa a los zombies (gracias a Stephane Chazelas por esta observación), que pueden eliminarse en función de su estado.
ps axl | awk '$7 != 0 && $10 !~ "Z"'
Para enumerar solo los PID:
ps -e -o pid= -o state= -o vsize= | awk '$2 != "Z" && $3 != 0 {print $1}'
En la práctica, encontré el siguiente idioma suficiente:
ps auxf | grep -v ]$
Filtra las líneas que terminan entre paréntesis, lo que puede resultar en la omisión de entradas no deseadas, pero es muy poco probable. A cambio, es bastante fácil de recordar y relativamente rápido de escribir.
Algunos procesos como avahi-daemon agregan a su información de nombre de proceso entre paréntesis (el nombre de host en el caso de avahi-daemon) y serán filtrados por este comando.
Una de las particularidades de esos procesos es que no están respaldados por un archivo ejecutable, por lo que podría hacer ( en zsh ):
ps /proc/[0-9]*/exe(^-@:h:t)
O con cualquier shell POSIX:
ps -p "$(find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3 | paste -sd , -)"
Eso es verificar los procesos cuyo /proc/<pid>/exe
es un enlace a un archivo.
Pero eso significa que debe ser superusuario para poder verificar el estado del /proc/<pid>/exe
enlace simbólico.
Editar : como sucede, los procesos zombies (al menos) satisfacen la misma condición, por lo que si no desea que se excluyan, tendrá que volver a agregarlos. Me gusta:
ps -p "$(
{ find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3
ps -Ao pid=,state= | sed -n 's/ Z//p'
} | paste -sd , -)"
Tenga en cuenta que ps -f
muestra esos nombres de proceso entre corchetes no porque sean procesos del núcleo, sino porque tienen un vacío argv[]
(por lo que ps muestra el nombre del proceso en lugar de argv[0]
allí). Puede tener un proceso de espacio de usuario con un espacio vacío argv[]
también y puede tener un nombre de proceso con un argv[0]
formulario que sea [some-string]
así que filtrar la ps
salida en función de esos corchetes no es una opción infalible.
zsh
sintaxis. El segundo es estándar POSIX sh
(y ps
y find
y cut
y paste
) sintaxis. Por supuesto, /proc
POSIX no lo especifica.
wc -l
). Bueno, entonces aceptaré la respuesta de Hauke Laging y te daré un voto positivo. ;)
También podría analizar el ps
resultado y buscar nombres de procesos que no estén entre paréntesis:
ps aux | awk '$NF!~/^\[.+\]$/'
awk -F: '$7 ~ home { print $1 }' /etc/passwd
- pero aún obtendrá procesos que mencionan dicho nombre de usuario, y dejará el archivo temporal por ahí. Retiraré mi voto negativo, pero solo porque su tercera solución es razonable.
$NF
es la última palabra de la línea de comando en la ps aux
salida. Los procesos no kernel pueden tener [...]
allí. Como dije en mi respuesta, la [xxx]
notación no se debe a que son procesos del núcleo, sino porque no tienen línea de comando (sin argumento), lo que también está permitido para los procesos que no son del núcleo.
Para cualquiera que intente esto en busybox donde ps
está muy simplificado y el resultado es diferente, esta variante de la gran respuesta de Gilles funciona bien:
ps -o pid,user,comm,vsz,stat | awk '$4 != 0 && $5 !~ "Z"'
Según la respuesta de Gilles, la metodología aquí es encontrar procesos que no usan memoria de usuario (`vsz col == 0) y filtrar procesos zombies (el estado col no es 'Z').
Las columnas de salida se pueden ajustar fácilmente, siempre que los números de campo awk basados en 1 se ajusten en consecuencia. Vea las opciones que tiene su ps disponible al poner un valor falso y se lo dirá. Por ejemplo:
$ ps -o foo
ps: bad -o argument 'foo', supported arguments: user,group,comm,args,pid,ppid,pgid,tty,vsz,stat,rss
Si solo necesita los recuentos ... Tenía una necesidad similar de filtrar los procesos kernel vs. usuario, pero solo necesitaba los respectivos recuentos de cada uno. Esta fue mi solución:
ps -eo vsize | awk '{p[$1==0]++} END {printf "%-16s %6d\n%-16s %6d\n%-16s %6d\n", "Kernel processes", p[1], "User processes", p[0], "Total processes", p[0]+p[1]}'
Salida de muestra :
Kernel processes 353
User processes 52
Total processes 405
Explicación : Estoy usando el truco de que se puede suponer que los procesos VSZ = 0 son procesos del núcleo. Entonces awk
, con , evalúo una comparación en VSZ (desde ps -eo vsize
), si es igual a cero. El resultado de la comparación será un booleano 0 o 1. Hago una matriz p[]
y, a medida que avanzo en la lista de procesos, si es un proceso de kernel, incremente p[1]++
. De lo contrario, como proceso de usuario, incremente p[0]++
. Después de todo el incremento, etiqueto e imprimo los valores (es decir, los recuentos) para p [0] y p [1] en el END { }
bloque.
Lo que estás buscando, mi amigo, no es ps
, pero pstree
.
Primero, identifique el primer proceso del núcleo. Su PID es comúnmente 1 en el sistema sin systemd y 2 con systemd.
Luego usa este comando:
$ pstree -p <1 or 2> | grep -o '([0-9]\+)' | grep -o '[0-9]\+'
La respuesta seleccionada (una con ✅) está usando otro comando:
$ ps --ppid 2 -p 2 --deselect
El problema con este ps
comando es que solo incluye hijos directos pero no todos los descendientes. El pstree
comando incluye a todos los descendientes. Puede comparar y contar la salida de estos dos comandos (una manera fácil es usar | wc
) para verificar.
kthreadd
siempre sea PID 2?