Как я могу закрыть терминал, не убивая его потомков (без запуска `screen` в первую очередь)?


35

иногда я запускаю приложение в gnome-терминале, но потом мне внезапно приходится перезапускать gnome или что-то в этом роде. Я думаю, что ответ на вопрос также полезен, тогда я хочу отключиться от SSH, где что-то происходит.

Терминальное дерево гнома выглядит так:

gnome-terminal
    bash
        some-boring-process

Могу ли я «отсоединиться» bashот gnome-terminal(или отсоединиться some-boring-processот bash и перенаправить его вывод куда-нибудь)? Если я просто убью gnome-terminal, bashбудут убиты все его подпроцессы


Ответы:


48

Если some-boring-processв вашей текущей сессии bash запущено:

  1. остановить его, ctrl-zчтобы дать вам приглашение bash
  2. положить его в фоновом режиме с bg
  3. запишите номер задания или воспользуйтесь jobsкомандой
  4. отсоедините процесс от этого сеанса bash с помощью disown -h %1(замените фактический номер задания там).

Это ничего не делает для перенаправления вывода - вы должны думать об этом, когда запускаете скучный процесс. [Редактировать] Кажется, есть способ перенаправить его https://gist.github.com/782263

А если серьезно, посмотрите на экран. У меня есть оболочки на удаленном сервере, которые работают уже несколько месяцев.


Спасибо. Я выбрал ваш ответ, потому что он был единственным, который отвечает на вопрос (речь шла о уже запущенном процессе). Я уже screenиногда использую , хотя у него есть свои проблемы, и я не хочу использовать его для каждой сессии bash в моей жизни
Валя

Вы используете его не для каждой сессии bash, а для каждой удаленной машины, на которой вы проводите много времени.
Гленн Джекман

Я позволил себе добавить информацию о перенаправлении вывода, пожалуйста, просмотрите его!
Валя

[root @ server ~] # bg -bash: bg: current: такой работы нет
Мухаммед Диас Яскур

Почему я получил bash: bg: current: no such job?
Мухаммед Диас Яскур

10

Именно для этого были созданы screen и tmux . Вы запускаете оболочку внутри сеанса screen / tmux и можете отключить / повторно подключиться по желанию. Вы также можете иметь несколько сессий оболочки, работающих внутри одного gnome-терминала.


Спасибо, но, как я прокомментировал принятый ответ: 1. Вопрос был о уже запущенном процессе. 2. screenимеет свои проблемы, и мне не хочется использовать его для каждой сессии bash в моей жизни
Валя

6

screen,, tmuxили dtach(возможно, с dvtm) все отлично подходит для этого, но если это то, что вы не думаете использовать один из них, вы можете использовать nohup.


Спасибо, но, как я прокомментировал принятый ответ: 1. Вопрос был о уже запущенном процессе. 2. screenимеет свои проблемы, и мне не хочется использовать его для каждой сессии bash в моей жизни
валя

@valya Рад, что вы нашли решение. Просто чтобы прояснить, однако, nohupработает ли запущенный процесс, используя -pопцию (если доступна).
Хэнк Гей

@ Хэнк Гей: Я не вижу -pвозможности nohupна страницах руководства; на какой системе вы работаете?
Микель

@Mikel Прежде чем я научился перестать беспокоиться и любить tmux, я использовал -pопцию на коробке Solaris. У меня также есть смутные воспоминания о том, как сделать это на CentOS-сервере Mongrel (возможно, zshесть встроенный модуль, который его поддерживает?), Но я не могу найти никаких документов по этому вопросу.
Хэнк Гей

@ Hank Gay: Ни в моей системе Ubuntu Linux, ни в ней bashнет . zshnohup
Микель

4

Если вы хотите продолжать взаимодействовать с дочерним процессом, а не просто создавать фон и продолжать его работу, на самом деле существует программа с именем retty, которая является проверкой концепции для «кражи» процесса из его текущего tty и повторного подключения к нему. текущий.

Однако он делает некоторые ужасные вещи, в том числе помещает некоторый ассемблерный код в стек повторно присоединенного приложения. И этот код не был обновлен для x86_64.

Есть другая программа, которая использует, возможно, лучший подход, замораживая процесс в пользовательском пространстве в файл, из которого он может быть впоследствии восстановлен (возможно, на другом tty). Это cryopid , и этот проект, похоже, также остановился в фаза проверки концепции, и она не работает с современным Linux, поскольку код стоит. Ах хорошо.

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


1
это напоминает мне о gist.github.com/782263 ... о, эта суть, кажется, тоже отвечает на мой вопрос
валя

2

Если я nohupзапускаю что- то, что хочу завершить, несмотря ни на что (кроме перезагрузки системы), я использую и запускаю это в фоновом режиме. В отличие от экрана и тому подобного, вы не можете присоединиться к процессам. Тем не менее, исключая перенаправление в любом другом месте, можно найти в nohup.out.

Я использую, screenкогда хочу иметь возможность переключать терминалы для процесса. Например, запуск процесса из дома / работы и переход к другому. Как и любой другой вывод сеанса терминала, в конечном итоге будет прокручиваться верхняя часть буфера.

РЕДАКТИРОВАТЬ: Если вы уже запустили процесс, вы можете disownзапретить HUPотправку сигнала при его закрытии.


Спасибо, но, как я прокомментировал принятый ответ: 1. Вопрос был о уже запущенном процессе. 2. screenесть свои проблемы, и я не хочу использовать его для каждой сессии bash в моей жизни
Валя

@valya Я видел ссылки на отключение запущенного процесса от группы программ. Я не знаю никаких инструментов для этого, хотя. Инструменту, вероятно, потребуется также перенаправить стандартные каналы ввода-вывода. Я думаю, что я мог заставить его работать один раз, но решил, что nohup был проще.
BillThor

1

Вы можете заставить процесс (PID) не получать сигнал HUP, когда терминальная сессия закончена. Используйте следующую команду:

nohup -p PID

nohup: invalid option -- 'p', Какую версию nohupвы используете в какой системе?
Anthon

Я в основном использую Solaris и AIX. Для Linux вы должны проверить в команде disown.
Тони

Да, в -pLinux нет выбора, поэтому этот ответ относится к Solaris и AIX. Полезно знать
Сергей Колодяжный

1

Этот скрипт отсоединяет дочерний процесс от родительского и назначает его процессу init :

toDetach=$1

./$toDetach & # Runs the process - script on background

disown -h %$(jobs -l | grep $(ps -A | grep $toDetach | cut --delimiter=' ' -f1) | cut --delimiter=' ' -f1 | tr -d '[]+') # and then disowns it from parents process
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.