Obter lista de processos que foram bifurcados em meu processo atualmente em execução?

3

Estou escrevendo um aplicativo de wrapper para bash scripts e quero que o aplicativo mantenha um controle de quais ferramentas / processos foram iniciados a partir de scripts de usuário. Gostaria de saber qual é a melhor maneira de determinar a lista de processos filhos gerados por este processo pai.

Eu tentei

  1. Invocando periodicamente o comando ps e criando uma árvore de processos (como ps -ejH), mas isso perde os processos que foram concluídos muito rapidamente.
  2. Usando uma ferramenta como forkstat que usa a interface do conector proc, mas que só seria executada com privilégios elevados. Enquanto isso dá os dados corretos, executando como sudo não funcionaria no meu caso?

Alguma sugestão de como isso pode ser alcançado?

    
por divyanshm 14.11.2018 / 13:00

4 respostas

4

Se você estiver usando o Linux, poderá usar strace para rastrear as chamadas do sistema usadas por um processo. Por exemplo:

~ strace -e fork,vfork,clone,execve -fb execve -o log ./foo.sh
foo bar
~ cat log
4817  execve("./foo.sh", ["./foo.sh"], [/* 42 vars */]) = 0
4817  clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f1bb563b9d0) = 4818
4818  execve("/bin/true", ["/bin/true"], [/* 42 vars */] <detached ...>
4817  --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=4818, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
4817  clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f1bb563b9d0) = 4819
4817  clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f1bb563b9d0) = 4820
4820  execve("/bin/echo", ["/bin/echo", "foo", "bar"], [/* 42 vars */] <detached ...>
4817  --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=4820, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
4817  +++ exited with 0 +++
4819  execve("/bin/sleep", ["sleep", "1"], [/* 42 vars */] <detached ...>

Você pode ver que o script bifurcou três processos (PIDs 4818, 4819, 4820) usando a chamada do sistema clone(2) , e as chamadas do sistema execve(2) nos processos bifurcados mostram os comandos executados.

  • -e fork,vfork,clone,execve limita a saída de strace para essas chamadas de sistema
  • -f segue processos filhos
  • -b execve se desconecta de um processo quando o execve é atingido, por isso não vemos mais rastreamento de processos filhos.
por 19.11.2018 / 04:26
3
pstree -p 'pgrep NetworkManager'
NetworkManager(1638)─┬─dhclient(3594)
                     ├─{NetworkManager}(1645)
                     ├─{NetworkManager}(1647)
                     └─{NetworkManager}(7363)

Acho que é isso que você estava procurando.

use pid ou pgrep direto com o nome do processo.

-p usado para imprimir pids de crianças.

    
por 19.11.2018 / 07:16
3
O comando

pgrep será útil. Use estes comandos:

Imprimir PIDs de cada processo bifurcado do processo ( $pid ):

pgrep -P $pid

Para informações mais detalhadas sobre cada processo bifurcado, use este comando:

ps -fp 'pgrep -P $pid'

em que $pid é o seu ID do processo.

    
por 18.11.2018 / 18:56
-1

I would like to know what is the best way to determine the list of child processes that were spawned of this parent process.

Assumindo que você está escrevendo no bash (você não diz). Então você pode usar o controle de trabalho. Isso está desativado por padrão, ao executar scripts.

O manual do bash diz:

set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
...
-m Monitor mode.
Job control is enabled. This option is on by default for interactive shells on systems that support it (see JOB CONTROL above). Background processes run in a separate process group and a line containing their exit status is printed upon their completion.

Portanto, adicione ao seu script set -m , você pode iniciar os comandos, com command & , e depois fazer jobs para listar os trabalhos.

    
por 20.11.2018 / 12:22