Eu gostaria de obter uma lista de todos os processos que descendem (por exemplo, filhos, netos, etc.) $pid
. Esta é a maneira mais simples de criar:
pstree -p $pid | tr "\n" " " |sed "s/[^0-9]/ /g" |sed "s/\s\s*/ /g"
Existe algum comando ou alguma maneira mais simples de obter a lista completa de todos os processos descendentes?
'\n'
delimitado x' '
delimitado). O caso de uso prático é: a) um script daemonizer que escrevi com puro masoquismo (especificamente, a funcionalidade "stop" tem que lidar com qualquer árvore de processos que o processo daemonized gerou); e b) um script tempo limite que vai matar qualquer que seja a excedido processo conseguiu criar.kill
. Veja unix.stackexchange.com/questions/9480/... , unix.stackexchange.com/questions/50555/...ps ax -opid,ppid,pgrp,cmd
vejo que existem muitos processos que compartilham o mesmopgrp
que a subárvore exata que quero matar. (Além disso, eu não posso ver osetpgrp
programa listado em qualquer lugar pacotes estável do Debian: packages.debian.org/... )Respostas:
A seguir, é um pouco mais simples e tem a vantagem adicional de ignorar números nos nomes dos comandos:
Ou com Perl:
Estamos procurando números entre parênteses, para não dar, por exemplo, 2 como um processo filho quando nos deparamos
gif2png(3012)
. Mas se o nome do comando contiver um número entre parênteses, todas as apostas serão desativadas. Até agora, o processamento de texto pode levá-lo.Então, eu também acho que os grupos de processos são o caminho a percorrer. Se você deseja que um processo seja executado em seu próprio grupo de processos, você pode usar a ferramenta 'pgrphack' do pacote Debian 'daemontools':
Ou você pode novamente recorrer ao Perl:
A única ressalva aqui é que os grupos de processos não se aninham; portanto, se algum processo estiver criando seus próprios grupos, seus subprocessos não estarão mais no grupo que você criou.
fonte
pstree -lp | grep -Po "(?<=\()\d+(?=\))"
fonte
bash
,zsh
,fish
, e até mesmoksh 99
), mas pode não funcionar em conchas mais velhos, por exemploksh 88
A versão mais curta que encontrei também lida corretamente com comandos como
pop3d
:Trata-se, erradamente, se você tem os comandos que têm nomes estranhos como:
my(23)prog
.fonte
ffmpeg
uso de threads. Embora, a partir de observações rápidas, pareça que os tópicos são dados com seu nome dentro de chaves{ }
,.Há também a questão da correção. Analisar ingenuamente a saída de
pstree
é problemático por vários motivos:Se você possui o Python e o
psutil
pacote instalado, pode usar este trecho para listar todos os processos descendentes:(O pacote psutil é, por exemplo, instalado como uma dependência do
tracer
comando que está disponível no Fedora / CentOS.)Como alternativa, você pode fazer uma travessia da árvore do processo pela primeira vez em uma casca de bourne:
Para calcular o fechamento transitivo de um pid, a parte da cauda pode ser omitida.
Observe que o acima não usa recursão e também é executado no ksh-88.
No Linux, pode-se eliminar a
pgrep
chamada e, em vez disso, ler as informações de/proc
:Isso é mais eficiente, porque economizamos um fork / exec para cada PID e fazemos
pgrep
algum trabalho adicional em cada chamada.fonte
Esta versão do Linux precisa apenas de proc e ps. É adaptado da última parte da excelente resposta de @ maxschlepzig . Esta versão lê / proc diretamente do shell, em vez de gerar um subprocesso em um loop. É um pouco mais rápido e sem dúvida um pouco mais elegante, como o título deste tópico solicita.
fonte
Em cada um dos seus dois casos de uso (aparentemente muito artificiais), por que você deseja eliminar alguns subprocessos de processos infelizes? Como você sabe melhor do que um processo quando seus filhos devem viver ou morrer? Isso parece um projeto ruim para mim; um processo deve limpar depois de si mesmo.
Se você realmente conhece melhor, deve estar criando esses subprocessos, e o 'processo daemonized' é aparentemente muito burro para se confiar
fork(2)
.Você deve evitar manter listas de processos filhos ou rastejar através da árvore de processos, por exemplo, colocando os processos filhos em um grupo de processos separado, conforme sugerido pelo @Gilles.
Em qualquer caso, suspeito que o seu processo daemon seria melhor criando um pool de threads de trabalho (que necessariamente morre junto com seu processo de contenção) do que uma árvore profunda de sub-sub-sub-processos, que algo em algum lugar precisa limpar .
fonte
Aqui está um script de wrapper pgrep que permite usar o pgrep e obter todos os descendentes ao mesmo tempo.
~/bin/pgrep_wrapper
:Invoque da mesma maneira que invocaria o pgrep normal, como
pgrep_recursive -U $USER java
para encontrar todos os processos e subprocessos Java do usuário atual.fonte
IFS
e usando matrizes ("${array[*]}
").