ID do grupo de processo de corrida, como posso matar o grupo?

2

Estou aprendendo sobre grupos de processos, uma coisa nova para mim. (Eu tento seguir este exemplo, inter alia: Por que o SIGINT não é propagado para o processo filho quando enviado para seu processo pai? ). Eu tento e não posso matar um grupo de processo, como é ID parece estar fugindo.

$ sleep 1000 &
[1] 6468
$ ps ax -O tpgid | grep sleep
 6468  6511 S pts/4    00:00:00 sleep 1000
 6512  6511 S pts/4    00:00:00 grep --color=auto sleep
$ kill -9 -6511
bash: kill: (-6511) - No such process
$ ps ax -O tpgid | grep sleep
 6468  6515 S pts/4    00:00:00 sleep 1000
 6516  6515 S pts/4    00:00:00 grep --color=auto sleep
$ ps ax -O tpgid | grep sleep
 6468  6517 S pts/4    00:00:00 sleep 1000
 6518  6517 S pts/4    00:00:00 grep --color=auto sleep

Por que isso acontece e como posso capturá-lo e matá-lo? O que estou recebendo e fazendo errado?

GNU bash, versão 4.3.42 (1) -release (x86_64-pc-linux-gnu)

    
por Tomasz 14.08.2016 / 15:47

1 resposta

4

Isso porque você não está imprimindo o ID do grupo de processos (PGID), está imprimindo o "código do grupo de processos tty de controle", tpgid. Conforme explicado em man ps :

   tpgid       TPGID     ID of the foreground process group on the tty
                         (terminal) that the process is connected to, or
                         -1 if the process is not connected to a tty.

Então, o que você está vendo é o PID do processo em primeiro plano, que, no seu caso, é o programa ps :

$ sleep 1000 &
[1] 6745
$ ps ax -O tpgid | grep -E 'sleep|ps a'
 6745  7136 S pts/1    00:00:00 sleep 1000
 7136  7136 R pts/1    00:00:00 ps ax -O tpgid
 7137  7136 S pts/1    00:00:00 grep --color -E sleep|ps a

como você pode ver acima, o valor de tpgid impresso é o PID do processo ps . O que você está procurando é pgid , não tpgid :

   pgid        PGID      process group ID or, equivalently, the process ID
                         of the process group leader.  (alias pgrp).


$ ps ax -O pgid | grep -E 'sleep|ps a'
 8414  8414 S pts/1    00:00:00 sleep 1000
 8656  8656 R pts/1    00:00:00 ps ax -O pgid
 8657  8656 S pts/1    00:00:00 grep --color -E sleep|ps a

Naturalmente, como você não está realmente executando nenhum grupo de processos (isso acontece quando, por exemplo, um script chama outros scripts), o PGID para sleep é o mesmo que seu PID. No entanto, você pode matá-lo dessa maneira se quiser:

$ kill -9 -8414
$ ps ax -O pgid | grep -E 'sleep|ps a'
10065 10065 R pts/1    00:00:00 ps ax -O pgid
10066 10065 S pts/1    00:00:00 grep --color -E sleep|ps a
[1]+  Killed                  sleep 1000

Um exemplo mais informativo seria executar um script como este:

#!/bin/bash

sleep 1000 &
sleep 1000 &
sleep 1000 &

sleep 1000

Se eu salvar isso como foo.sh e executá-lo, os vários comandos sleep terão o mesmo PGID:

$ foo.sh &
[1] 13555
$ ps ax -O pgid | grep -P '[s]leep|[f]oo.sh'
13555 13555 S pts/1    00:00:00 /bin/bash /home/terdon/scripts/foo.sh
13556 13555 S pts/1    00:00:00 sleep 1000
13557 13555 S pts/1    00:00:00 sleep 1000
13558 13555 S pts/1    00:00:00 sleep 1000
13559 13555 S pts/1    00:00:00 sleep 1000

Assim, cada processo filho está no grupo de processos do pai, foo.sh . Se nós agora matarmos o grupo de processos, todos os processos sairão:

$ kill -9 -13555
$ ps ax -O pgid | grep -P '[s]leep|[f]oo.sh'
[1]+  Killed                  foo.sh
    
por 14.08.2016 / 16:09

Tags