Как я могу отречься от запущенного процесса и связать его с новой оболочкой экрана?


159

У меня запущена программа на SSH-оболочке. Я хочу приостановить его и иметь возможность приостановить его выполнение, когда вернусь.

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

Есть ли другой способ продолжить?


8
См. Также Могу ли я выполнить nohup / screen уже запущенного процесса? и команда Resume, запущенная в отброшенном сеансе SSH , в которой упоминается несколько решений на основе ptrace, которые (в настоящее время) не упомянуты здесь.
Жиль

Из таких вопросов, как unix.stackexchange.com/a/4039/13496, я слышу о retty и neercs . Хммм ... интересно, есть ли что-то вроде слоя " экран здесь", прежде чем я запущу процесс в следующий раз, если я потеряю верхний терминал в будущем, что позволит легко вернуться обратно в stdin / out / err
Marcos

Вторичная / неявная проблема в этом вопросе, которую я не могу понять: почему оболочка решила отменить приостановленную работу, когда есть более новая / только что запущенная в фоновом режиме , которая даже не нуждается в / ждет stdin? Это то лечение, к которому я привык, поэтому не знаю, что здесь изменилось ...
Маркос

Ответы:


86

Использование GNU screen- ваш лучший выбор.

Начать запуск экрана при первом входе в систему - я запускаю screen -D -R, запускаю вашу команду и отключаю или приостанавливаю ее, CTRL-Zа затем отключаюсь от экрана, нажимая CTRL-Aзатем D.

При повторном входе в систему снова подключитесь, запустив screen -D -R. Вы будете в той же оболочке, что и раньше. Вы можете запустить, jobsчтобы увидеть приостановленный процесс, если вы это сделали, и запустить %1(или соответствующее задание #), чтобы снова поставить его на передний план.


2
Ничего себе, я не могу поверить, что ответ GNU Screen в настоящее время имеет самый низкий рейтинг. Я что-то пропустил?
Фахим Митха

1
Может быть! Похоже, лучшее для меня.
Андрей Йохум

1
Оглядываясь назад, можно сказать, что это наиболее безболезненное решение, при условии, что вы можете соответствующим образом планировать и запускать свои процессы из среды экрана. В любом случае, я сделал это официальным ответом!
Levesque

28
Я думаю, что это не отвечает на вопрос. Вопрос начинается с " У меня запущена программа ". Этот ответ предполагает, что он еще не запущен ...
Анко

да, он ясно написал, что хочет получить его на экране :-)
Флориан Хейгл

112

Вы можете отозвать «владение» программой из оболочки с помощью disownвстроенного:

# press Ctrl+Z to suspend the program
bg
disown

Однако это только говорит оболочке не отправлять SIGHUPсигнал программе при выходе из оболочки. Программа сохранит любое соединение с терминалом, как правило, в виде стандартных потоков ввода, вывода и ошибок. Нет возможности подключить их к другому терминалу. ( Экран работает, эмулируя терминал для каждого окна, поэтому программы прикрепляются к окну экрана.)


Можно повторно присоединить файловые дескрипторы к другому файлу, подключив программу в отладчике (т.е. используя ptrace) и сделав ее вызовом open, dupи close. Есть несколько инструментов, которые делают это; это сложный процесс, и иногда они могут привести к сбою процесса. Возможности включают (ссылки, собранные из ответов на Как я могу отречься от запущенного процесса и связать его с новой экранной оболочкой? И могу ли я nohup / screen уже запущенный процесс? ):


disownудаляет процесс из списка управления заданиями.
Ctrl-Alt-Delor

3
Почему нет disown -h?
Сис Тиммерман

@CeesTimmerman Это оставляет работу в таблице рабочих мест оболочки, но в чем ее преимущество?
Жиль

@ Жиль: так что вы можете еще fgили killэто, и посмотреть, закончится ли он сам по себе.
Питер Кордес

Какие упомянутые утилиты работают с группой процессов (например bzcat a.bz2 | grep text)? Человек для reptyrговорит, что не поддерживает перемещение процессов с детьми.
dma_k

64

Для перемещения процесса между терминалами или для повторного подключения отключенного, вы можете использовать, например, reptyr .


1
Да, это спасло это, спасибо! Я прочитал сайт автора, как он работает лучше, чем аналогичные или старые инструменты, например. для программ ncurses.
Маркос

4
Это круто; это должно решить затруднительное положение друга - постоянно терять свою работу, выполняя ее прямо в ssh, а затем нужно садиться в поезд. "Ой, забыл использовать экран. Снова."
Адам Кац

3
+1 Хотя принятый screenответ, конечно, идеален, на самом деле он не отвечает на вопрос, в котором конкретно запрашивается способ перемещения текущего запущенного процесса screenили тому подобное. Также смотрите этот ответ: serverfault.com/a/284795
toxefa

1
Абсолютная живая заставка. Позволил мне повторно присоединиться к запуску apt dist-upgrade, который ожидал подтверждения пользователя.
andig

28

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

Когда вы отсоединились от предыдущего сеанса, вы можете безопасно закрыть терминал; позже используйте, tmux attachчтобы вернуться к сеансу, даже если вы вышли из системы.


1
Вы также можете поделиться своим сеансом с вашим другом и использовать несколько окон и панелей и многое другое! люблю это ^ _ ^
игорь

пример использования пожалуйста?
Виталий Зданевич

21

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


19

Я не использую это регулярно, но претензии neercs, чтобы поддержать это. Это screenпохожая программа с различными необычными функциями, такими как улучшенное управление панелями, но главное, что она предлагает, это возможность импортировать процесс в панель.


2
Интересно. Он воспроизводит dirty ( ptrace), но он не просто манипулирует дескрипторами файлов, он разветвляет процесс. Он может захватить find /, но разбился интерактивный удар.
Жиль

@ Жиль, я не могу вспомнить, как все прошло, когда я пытался, но у него нет хорошей репутации, мне говорят, что он довольно часто терпит неудачу
Майкл Мрозек

9

Если вы просто хотите приостановить его и перезапустить после, вы можете использовать killс STOPили CONTсигнал.

Сначала выясните процессы PID с

$ ps aux

Затем отправьте сигналы этому PID, указанному в процессе

$ kill -STOP <PID>

$ kill -CONT <PID>

9

"injcode" от ThomasHabets, кажется, именно то, что мне нужно:

https://github.com/ThomasHabets/injcode

Программа injcode позволяет вводить произвольный код в работающий процесс, вне зависимости от того, знали ли вы заранее и работали screen или tmux

Из README:

Пример 1: переместить irssi из одного терминала в другой

Может быть, переместить его в экран.

Сначала запустите irssi в одном терминале.

Запустите injcode в другом терминале: $ injcode -m retty

Irssi теперь должен быть перенесен на второй терминал, включая новый управляющий терминал.


1

Это сработало для меня:

  1. bg процесс
  2. jobs -l найти номер процесса
  3. tmux запустить менеджер окон оболочки
  4. reptyr -L PROCESSNUMBER

reptyr«s -Lбыло необходимо , чтобы получить эту работу:

-L Like '-l', but also redirect the child's stdio to the slave.

из-за этой ошибки:

$ reptyr 30622

[-] Unable to open the tty in the child.
Unable to attach to pid 30622: Permission denied

И с -L

$ reptyr -L 30622
Opened a new pty: /dev/pts/4
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.