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.