Як я можу відхилити запущений процес і пов’язати його з новою оболонкою екрана?


159

У мене працює програма на оболонці SSH. Я хочу призупинити його і зможу скасувати його виконання, коли я повернусь.

Один із способів, який я думав зробити це, - це передати свою власність на екранну оболонку, таким чином, утримуючи її там.

Чи є інший спосіб поступити?


8
Див. Також Чи можна ногуп / екранувати вже розпочатий процес? і команда Resume, запущена в сеансі , що випав із SSH , де згадуються декілька рішень на основі ptrace, про які (наразі) не згадується тут.
Жиль

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

Вторинна / неявна проблема в цьому питанні, яку я не можу зрозуміти, це ... чому оболонка вирішила відмовитись від призупиненої роботи, коли є нова / щойно запущена в фоновому режимі , яка навіть не потребує / чекає stdin? Це лікування, до якого я звик, тому не знаю, що тут
різнилося

Відповіді:


86

Використання GNU screen- найкраща ставка.

Початковий екран працює під час першого входу - я запускаю screen -D -R, запускаю вашу команду, або відключаю або призупиняю її, CTRL-Zа потім відключаюсь від екрана, натискаючи CTRL-Aпотім D.

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


2
Нічого собі, я не можу повірити, що відповідь GNU Screen на даний момент є найнижчою. Я щось пропускаю?
Faheem Mitha

1
Можливо! Мені здається, що найкраще.
Андрій Йохум

1
Озираючись назад, воно, очевидно, є найбільш безболісним рішенням, за умови, що ви зможете відповідно спланувати та запустити свої процеси із екранного середовища. У всякому разі, я зробив це офіційною відповіддю!
levesque

28
Я думаю, це не відповідає на питання. Питання починається з " У мене працює програма ". Ця відповідь припускає, що вона ще не працює…
Анко

так, він чітко написав, що хоче потрапити на екранну сесію :-)
Флоріан Хейгл

112

Ви можете відкликати "право власності" на програму з оболонки за допомогою disownвбудованого:

# press Ctrl+Z to suspend the program
bg
disown

Однак це говорить тільки оболонці не надсилати SIGHUPсигнал програмі, коли оболонка виходить. Програма зберігає будь-яке з'єднання, яке вона має з терміналом, як правило, як стандартні потоки вводу, виводу та помилок. Немає способу приєднати їх до іншого терміналу. ( Екран працює, емулюючи термінал для кожного вікна, тому програми додаються до вікна екрану.)


Можна повторно приєднати fileescriptors до іншого файлу, приєднавши програму до налагоджувача (тобто використовуючи ptrace) та зробивши її викликом open, dupта close. Є кілька інструментів, які роблять це; це складний процес, і іноді вони замінять процес. Можливості включають в себе (посилання , зібрані з відповідей на Як я можу відректися запущеним процес і зв'язати його з новою оболонкою екрану? І я можу поЬір / екранувати вже розпочатий процес? ):


disownвидаляє процес зі списку контрольних завдань.
ctrl-alt-delor

3
Чому ні disown -h?
Cees Timmerman

@CeesTimmerman Це залишає роботу в таблиці завдань оболонки, але в чому перевага цього?
Жиль

@Gilles: так що ви можете ще fgй killце, і подивитися , якщо він закінчується сам по собі.
Пітер Кордес

Які згадані утиліти працюють з групою процесів (наприклад bzcat a.bz2 | grep text)? Людина reptyrкаже, що вона не підтримує рух процесів з дітьми.
dma_k

64

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


1
Так, це врятувало, дякую! Я читаю веб-сайт автора, як він працює краще, ніж подібні чи старіші інструменти, наприклад. для ncurses програм.
Маркос

4
Це круто; це повинно вирішити важкий стан друга, який постійно втрачає роботу, запускаючи її прямо в сш, а потім потрібно сідати в поїзд. "На жаль, забув використовувати екран. Знову."
Адам Кац

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

1
Абсолютна жива заставка. Дозволено мені знову приєднатися до запущеного apt dist-upgrade, який сидів на очікуванні підтвердження користувача.
andig

28

Моє улюблене рішення - це використання tmux, ви можете відключити сеанс і знову приєднати його до іншого терміналу.

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


1
Ви також можете поділитися своїм сеансом з ур-другом і використовувати кілька вікон та панелей і багато іншого! love it ^ _ ^
igor

Приклад використання будь ласка?
Віталій Зданевич

21

Існує також невелика утиліта під назвою retty, яка дозволяє повторно приєднувати запущені програми до іншого терміналу.


19

Я не використовую її регулярно, але стверджує, що неєркс підтримує це. Це screenподібна програма з різними фантазійними функціями, такими як покращення керування панелями, але головне, що вона пропонує, - це можливість імпортувати процес на панель


2
Цікаво. Він грає брудно ( ptrace), але не просто маніпулює дескрипторами файлів, а розгортає процес. Він здатний схопити find /, але розбив інтерактивний баш.
Жиль

@Gilles Я не можу пригадати, як це пройшло, коли я спробував, але це не має великої репутації, мені кажуть, що це виходить досить регулярно
Michael Mrozek

9

Якщо ви просто хочете , щоб призупинити і перезапустити після цього, ви можете використовувати killз STOPабо CONTсигнал.

Спочатку з’ясуйте процеси, з допомогою яких PID

$ ps aux

Потім направляйте сигнали до того PID, який перерахований до процесу

$ kill -STOP <PID>

$ kill -CONT <PID>

9

"injcode" від ThomasHabets, здається, саме те, що мені потрібно:

https://github.com/ThomasHabets/injcode

Програма injcode дозволяє вводити до запущеного процесу довільний код, незалежно від того, ви заздалегідь знали чи не працювали на екрані чи tmux

З ПРОЧИТАННЯ:

Приклад 1: переміщення irssi з одного терміналу на інший

Можливо, перемістіть його на екран.

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

Запустіть injcode в інший термінал: $ injcode -m retty

Тепер Irssi слід перенести на другий термінал, включаючи новий термінал управління.


1

Це працювало для мене:

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

reptyrЦе -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.