Как разветвить процесс на другой виртуальный терминал

Мне нужен способ разветвить текущий процесс на другой виртуальный терминал. На самом деле я хочу создать дочерние элементы моего процесса в отдельных панелях tmux, но знание того, как перейти на другую консоль, подойдет, остальное должно быть легко.

В ответ на ваш комментарий «На этот вопрос нет одобренного или принятого ответа». Просто примите свой ответ, и вы сможете использовать его в качестве дублирующей цели.

mozway 07.05.2024 20:56

@mozway: В stackoverflow.com/questions/33155143/… dbc добавлен «похожий» комментарий. Если это правильно и не будет удалено, я бы предпочел именно так, а не дублировать флаг. поскольку эти вопросы и ответы не являются точными копиями друг друга

dhyan.nataraj 09.05.2024 06:34
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
84
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Перенос одного процесса в другой терминал

Сначала давайте посмотрим, как перенести один процесс в другую консоль. В Linux вы можете использовать Reptyr для повторного подключения процесса к другому терминалу. Это довольно легко.

Давайте представим, что это ваша основная программа:

#!/usr/bin/perl

print "My PID is $$\n"; # print current process PID;
sleep 10;

while(1){
  print ++$i, "\n";
  sleep 1;
}

Он напечатает свой собственный PID, а затем через некоторое время начнет отсчитывать секунды.

Тебе следует бежать

reptyr [PID-number]

в новом терминале (поместите PID, напечатанный программой, вместо [PID-number]), и вы увидите, что наша основная программа будет перенесена в этот новый терминал.

Вполне легко

Перемещение дочернего процесса в другой терминал

Если вы попытаетесь проделать этот трюк с новым разветвленным процессом, reptyr потерпит неудачу со следующей ошибкой:

[-] Process 739989 (test2.pl) shares 739990's process group. Unable to attach.
(This most commonly means that 739990 has sub-processes).
Unable to attach to pid 739990: Invalid argument

Когда вы создаете форк, он начинает совместно использовать группу с родительским процессом (ссылка на статью, объясняющую работу группы процессов, находится в конце этой статьи). По какой-то причине вы reptyr не можете перехватить процесс, принадлежащий группе. Чтобы использовать reptyr в этом дочернем процессе, вам следует разгруппировать его или, точнее, установить его в отдельную группу, вызвав setpgid($$, $$), который назначит текущий процесс группе с идентификатором процесса ID текущего процесса. Это переместит ребенка в свою группу, и reptyr сможет его «вырвать».

#!/usr/bin/perl

use POSIX;

$pid = fork();
if ($pid)
{
  # parent process
  print "Child PID is $pid\n";
  sleep 10;
  while (1) {print ".\n"; sleep 1};
} else
{
  # child process
  (setpgid($$,$$) != -1)           || die "Can't set own group: $!";
  sleep 10;
  while (1) {print ++$i,"\n"; sleep 1};
}

Здесь родительский процесс печатает точки, а дочерний процесс считает секунды. Он также печатает дочерний PID в начале.

Если вы ничего не сделаете, вывод родительского и дочернего элементов будет перемешан в терминале, в котором вы его запустили. Но если ты побежишь

reptyr [child-PID-number]

в новом терминале (поместите дочерний PID, напечатанный программой, вместо [child-PID-number]) вы увидите, что вывод родительской программы (точки) останется в старом терминале, а вывод дочерней программы (числа) будет перенесен на новый терминал.

Смотрите также

Для лучшего понимания работы групп процессов вам следует прочитать эту статью: https://blog.nelhage.com/2011/02/changing-ctty/

Другие вопросы по теме

Похожие вопросы

Сценарий оболочки – как отображать имена переменных и их значения в цикле
Почему Listen() (до вызова Accept()) достаточно, чтобы приложение завершило трехстороннее рукопожатие?
Попытка передать «указатель на структуру данных» обработчику сигнала с помощью функции sigqueue из одного процесса в другой, используя структуру siginfo_t
Awk: попробуйте преобразовать строку временной метки во время эпохи Unix
Как уничтожить/освободить объект FILE, не закрывая базовый файловый дескриптор?
Синтаксис для извлечения имени файла.ext*, но не имени файла.ext*.*
Обработать текстовый файл, чтобы изменить значение столбца на основе максимального значения из другого столбца
Почему getchar() зависает, несмотря на то, что poll() возвращает «хорошее» значение?
Необходимо ли использовать fflush более одного раза?
Регулярное выражение Sed находит строку в yaml и строку комментария, сохраняя отступы