Me gustaría obtener una lista de todos los procesos que descienden (por ejemplo, hijos, nietos, etc.) $pid
. Esta es la forma más simple que se me ocurrió:
pstree -p $pid | tr "\n" " " |sed "s/[^0-9]/ /g" |sed "s/\s\s*/ /g"
¿Hay algún comando, o alguna forma más simple de obtener la lista completa de todos los procesos descendientes?
'\n'
delimitado frente a' '
delimitado). El caso de uso práctico es: a) un script daemonizer que escribí por puro masoquismo (específicamente, la funcionalidad "stop" tiene que lidiar con cualquier árbol de procesos que generó el proceso demonizado); y b) una secuencia de comandos de tiempo de espera que matará a cualquiera que sea el tiempo de espera superado el proceso se gestiona a crear.kill
. Ver unix.stackexchange.com/questions/9480/… , unix.stackexchange.com/questions/50555/…ps ax -opid,ppid,pgrp,cmd
Veo que hay muchos procesos que comparten lo mismopgrp
que el subárbol exacto que quiero matar. (Además, no puedo ver elsetpgrp
programa en ninguna parte de los paquetes estables de Debian: packages.debian.org/… )Respuestas:
Lo siguiente es algo más simple y tiene la ventaja adicional de ignorar los números en los nombres de los comandos:
O con Perl:
Estamos buscando números entre paréntesis para no dar, por ejemplo, 2 como un proceso secundario cuando nos encontramos
gif2png(3012)
. Pero si el nombre del comando contiene un número entre paréntesis, todas las apuestas están desactivadas. Hasta ahora solo puede llevarte el procesamiento de texto.Así que también creo que los grupos de procesos son el camino a seguir. Si desea ejecutar un proceso en su propio grupo de procesos, puede utilizar la herramienta 'pgrphack' del paquete Debian 'daemontools':
O podrías volver a Perl:
La única advertencia aquí es que los grupos de procesos no anidan, por lo que si algún proceso está creando sus propios grupos de procesos, sus subprocesos ya no estarán en el grupo que usted creó.
fuente
pstree -lp | grep -Po "(?<=\()\d+(?=\))"
fuente
bash
,zsh
,fish
, e inclusoksh 99
), pero puede que no funcione en cáscaras de más edad, por ejemploksh 88
La versión más corta que he encontrado que también trata correctamente con comandos como
pop3d
:Se ocupa erróneamente si tiene comandos que tienen nombres extraños como:
my(23)prog
.fuente
ffmpeg
uso de hilos. Sin embargo, a partir de observaciones rápidas, parece que los hilos se dan con su nombre dentro de llaves,{ }
.También está la cuestión de la corrección. Analizar ingenuamente la salida de
pstree
es problemático por varias razones:Si tiene Python y el
psutil
paquete instalado, puede usar este fragmento para enumerar todos los procesos descendientes:(El paquete psutil se instala, por ejemplo, como una dependencia del
tracer
comando que está disponible en Fedora / CentOS).Alternativamente, puede hacer un recorrido transversal del árbol de procesos en un shell de bourne:
Para calcular el cierre transitivo de un pid, se puede omitir la parte de cola.
Tenga en cuenta que lo anterior no usa recursividad y también se ejecuta en ksh-88.
En Linux, uno puede eliminar la
pgrep
llamada y en su lugar leer la información de/proc
:Esto es más eficiente porque guardamos un fork / exec para cada PID y hacemos un
pgrep
trabajo adicional en cada llamada.fuente
Esta versión de Linux solo necesita / proc y ps. Está adaptado de la última parte de la excelente respuesta de @ maxschlepzig . Esta versión lee / proc directamente desde el shell en lugar de generar un subproceso en un bucle. Es un poco más rápido y posiblemente un poco más elegante, como lo solicita este título de hilo.
fuente
En cada uno de sus dos casos de uso (aparentemente muy artificiales), ¿por qué quiere matar los subprocesos de algunos procesos desafortunados? ¿Cómo sabes mejor que un proceso cuando sus hijos deberían vivir o morir? Esto me parece un mal diseño; un proceso debe limpiarse después de sí mismo.
Si realmente sabe mejor, entonces debería estar bifurcando estos subprocesos, y el 'proceso demonizado' es aparentemente demasiado tonto para confiar en él
fork(2)
.Debe evitar mantener listas de procesos secundarios o avanzar por el árbol de procesos, por ejemplo, colocando los procesos secundarios en un grupo de procesos separado como lo sugiere @Gilles.
En cualquier caso, sospecho que su proceso demonizado sería mejor creando un grupo de subprocesos de trabajo (que necesariamente muere junto con su proceso de contención) que un árbol profundo de sub-sub-sub-subprocesos, que algo en algún lugar luego tiene que limpiar .
fuente
Aquí hay un script de envoltorio pgrep que le permite usar pgrep y obtener todos los descendientes al mismo tiempo.
~/bin/pgrep_wrapper
:Invoque de la misma manera que invocaría pgrep normal, como
pgrep_recursive -U $USER java
para encontrar todos los procesos y subprocesos Java del usuario actual.fuente
IFS
y el uso de matrices ("${array[*]}
").