Intereting Posts

Отказ от ребенка от родительского процесса

Если $ PID_PARENT запустил $ PID_CHILD, как я могу отсоединить ( disown ) $ PID_CHILD от $ PID_PARENT, чтобы, когда я убиваю $ PID_PARENT, $ PID_CHILD продолжал работать, как будто ничего не произошло?

Конкретно, мой $ PID_PARENT – это процесс, выполняющий Jenkins (или процесс Java который запускает сервер, на котором выполняется Jenkins), а $ PID_CHILD – это очень длинная работа, которую мне не нужно перезапускать после перезапуска Jenkins (что необходимо для некоторых поддержание). По сути, я хочу остановить Дженкинса, но не прекращать долгую работу, которую он начал, и я знаю оба PID.

ОБНОВЛЕНИЕ 1: Я узнал об отключении и попробовал из оболочки входа в систему (поэтому не родительской оболочки PID):

 disown $PID_CHILD 

но получил

-bash: отречься: 13924: такой работы нет

$ PID_CHILD правильно и делает

 ps -o ppid= $PID_CHILD 

возвращает $ PID_PARENT

ОБНОВЛЕНИЕ 2: Согласно ответу @ Rui, я сделал временную работу по взлому в Jenkins, которая на этот раз запускается только из родительской оболочки:

 disown 13924 

но все же получил

Отклонение: 13924: нет такой работы – амфибия

Один из способов – отсоединить дочерний процесс от родительского. Для этого потребуется соответствующий код в дочернем процессе или скрипт-обертка, который выполняет диссоциацию перед выполнением реального кода:

 #!/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; 

который, если он сохранен как solitary может быть протестирован с помощью чего-то вроде:

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

с использованием logger(1) потому что все стандартные файловые дескрипторы были закрыты как часть диссоциации. Возможно, их придется перенаправить в другое место для вашего приложения.

Обратите внимание, что это может быть невозможно, если Jenkins (или systemd, или что-то еще) использует пространство имен PID, из которого процесс не может выйти независимо от того, как он себя разветвляет, и в этом случае вам понадобится какое-то решение на уровне контейнера, или чтобы вернуться к тому, что вы пытаюсь сделать.

Я думаю, что вы должны быть в состоянии сделать

 $ disown $PID 

Затем, если вы прекратите сеанс оболочки, процесс все равно будет запущен.

Вы должны сделать свое disown от оболочки, которая назвала процесс. Следовательно, звоня из другой оболочки, вы получаете сообщение « no such job

Чтобы фактически отречься от процесса и сказать ему игнорировать сигнал зависания, вы должны сделать это из оболочки, которая вызвала процесс:

 disown -h $PID 

От отрешиться помогите:

$ disown –help disown: disown [-h] [-ar] [jobspec … | пид …]
Удалить задания из текущей оболочки.

  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. 

При создании фонового процесса, который сохраняется после завершения сборки Jenkins, вам необходимо следить за средством Jenkins Process Tree Killer . Когда assembly завершается, средство удаления дерева процессов пытается уничтожить все процессы, связанные с этой сборкой, даже если процессы были отменены из процесса сборки и более не являются дочерними процессами процесса сборки.

В приведенной выше ссылке есть инструкции о том, как отключить средство блокировки дерева процессов для определенных заданий или для Jenkins в целом.