Desprovando filho do processo pai

0

Se $ PID_PARENT lançou $ PID_CHILD, como posso desanexar ( disown ?) $ PID_CHILD de $ PID_PARENT para que, quando eu matar $ PID_PARENT, $ PID_CHILD continue correndo como se nada tivesse acontecido?

Concretamente, meu $ PID_PARENT é o processo em execução Jenkins (ou o Java processo que executa o servidor que executa o Jenkins) e $ PID_CHILD é um trabalho muito longo que não quero reiniciar após a reinicialização Jenkins (que é necessário para alguma manutenção). Essencialmente, eu quero parar Jenkins, mas não parar o longo trabalho que começou e eu conheço ambos os PIDs.

UPDATE 1: Descobri disown e tentei de um shell de login (portanto, não o shell PID pai):

disown $PID_CHILD

mas tem

-bash: disown: 13924: no such job

O $ PID_CHILD correto e fazendo

ps -o ppid= $PID_CHILD

retorna $ PID_PARENT

UPDATE 2: De acordo com a resposta do , fiz um hack temporário trabalho no Jenkins que é executado apenas a partir do shell pai desta vez:

disown 13924 

mas ainda tem

disown: 13924: no such job – amphibient

    
por amphibient 27.06.2018 / 17:44

4 respostas

2

Uma maneira é fazer com que o processo filho se desassocie do pai. Isso exige código adequado no processo filho ou um script de wrapper que realiza a dissociação antes de executar o código real:

#!/usr/bin/env perl
use strict;
use warnings;
die "Usage: $0 command [args ..]\n" unless @ARGV;
# diassociate this process (some folks also do a double-fork thing)
use POSIX "setsid";
chdir("/") || die "can't chdir to /: $!";
open( STDIN,  "< /dev/null" ) || die "can't read /dev/null: $!";
open( STDOUT, "> /dev/null" ) || die "can't write to /dev/null: $!";
defined( my $pid = fork() ) || die "can't fork: $!";
exit if $pid;    # non-zero now means I am the parent
( setsid() != -1 ) || die "Can't start a new session: $!";
open( STDERR, ">&STDOUT" ) || die "can't dup stdout: $!";
# and replace ourself with whatever we were called with
exec @ARGV;

que, se salvo como solitary , pode ser testado por meio de algo como:

% ./solitary logger greppable
% grep greppable /var/log/system.log
Jun 27 10:52:15 hostn jhqdoe[20966]: greppable
% 

com o uso de logger(1) porque os filehandles padrão foram todos fechados como parte da dissociação. Estes podem precisar ser redirecionados para outro lugar para o seu aplicativo.

Note que isso pode não ser possível se Jenkins (ou systemd ou qualquer outro) usar um namespace PID que o processo não possa escapar, não importa como ele se bifurque, caso em que você precisaria de alguma solução em nível de contêiner, ou revisitar o que você está tentando fazer.

    
por 27.06.2018 / 19:54
1

Eu acho que você deve ser capaz de simplesmente fazer

$ disown $PID

Então, se você encerrar sua sessão de shell, o processo ainda estará em execução.

    
por 27.06.2018 / 17:50
1

Você precisa fazer seu disown do shell que chamou o processo. Daí chamando de outro shell você recebe a mensagem no such job .

Para realmente deserdar um processo e dizer a ele para ignorar o sinal de desconexão, você faria do shell que chamou o processo:

disown -h $PID

De ajuda negativa:

$ disown --help disown: disown [-h] [-ar] [jobspec ... | pid ...]
Remove jobs from current shell.

    Removes each JOBSPEC argument from the table of active jobs.  Without
    any JOBSPECs, the shell uses its notion of the current job.

    Options:
      -a    remove all jobs if JOBSPEC is not supplied
      -h    mark each JOBSPEC so that SIGHUP is not sent to the job if the
                    shell receives a SIGHUP
      -r    remove only running jobs

    Exit Status:
    Returns success unless an invalid option or JOBSPEC is given.
    
por 27.06.2018 / 18:16
1

Ao criar um processo em segundo plano que persista após a conclusão de uma compilação do Jenkins, você precisará estar atento ao Jenkins Process Tree Killer . Quando uma compilação sai, o matador da árvore de processos tenta eliminar todos os processos relacionados a essa compilação, mesmo que os processos tenham sido renegados do processo de compilação e não sejam mais processos filhos do processo de compilação.

Há instruções no link acima para saber como desativar o matador de árvore de processos para tarefas específicas ou para o Jenkins como um todo.

    
por 28.06.2018 / 18:00