Могу ли я выполнить nohup / screen уже запущенного процесса?

260

Я делаю несколько тестовых прогонов долгосрочных сценариев переноса данных через SSH. Допустим, я начинаю запускать сценарий около 16:00; сейчас 6 вечера катается, и я проклинаю себя за то, что не сделал все это screen.

Есть ли какой-нибудь способ «задним числом» nohupпроцесса или мне нужно оставить компьютер включенным всю ночь? Если невозможно подключиться screenк / nohupпроцессу, который я уже начал, то почему? Как-то связано с тем, как взаимодействует родитель / ребенок? (Я не приму ответ «нет», который по крайней мере не отвечает на вопрос «почему» - извините;))

ojrac
источник
4
Только что увидел интересный пост в блоге о disown. blogs.oracle.com/ksplice/entry/disown_zombie_children_and_the
ojrac

Ответы:

212

Если вы используете Bash, вы можете запустить disown -h job

отрекаться

disown [-ar] [-h] [jobspec ...]

Без опций каждая спецификация заданий удаляется из таблицы активных заданий. Если -hуказан этот параметр, задание не удаляется из таблицы, а помечается так, что SIGHUP не отправляется заданию, если оболочка получает SIGHUP. Если спецификация заданий отсутствует и не указана -aни -rопция, ни текущее задание. Если спецификация -a заданий не указана, опция означает удалить или отметить все задания; -rвариант без jobspec аргумента ограничивает операцию выполнения заданий.

gharper
источник
Потрясающие; Я надеялся, что что-то подобное появится.
ojrac
7
Жизнь может быть несправедливой. gharper и я выкладывали это примерно в одно и то же время :)
serverhorror
4
Ты мой герой
Томас Диньян
9
отрицать не является специфическим для Баш. Это также в zsh, ksh93, ...
Phil P
2
Я обнаружил, что вам действительно нужно использовать, disown %1если 1 - это bg 1 спецификация
задания
81

Используйте reptyr

Из README:

reptyr - A tool for "re-ptying" programs.
-----------------------------------------

reptyr is a utility for taking an existing running program and
attaching it to a new terminal. Started a long-running process over
ssh, but have to leave and don't want to interrupt it? Just start a
screen, use reptyr to grab it, and then kill the ssh session and head
on home.

USAGE
-----

  reptyr PID

"reptyr PID" will grab the process with id PID and attach it to your
current terminal.

After attaching, the process will take input from and write output to
the new terminal, including ^C and ^Z. (Unfortunately, if you
background it, you will still have to run "bg" or "fg" in the old
terminal. This is likely impossible to fix in a reasonable way without
patching your shell.)

Несколько сообщений в блоге его автора:

Джонатан Тран
источник
Я собираюсь придерживаться встроенных инструментов (то есть отречься), но это не так гибко, как reptyr. +1
ojrac
22

Чтобы украсть процесс от одного tty до вашего текущего tty, вы можете попробовать этот хак:

http://www.ucc.asn.au/~dagobah/things/grab.c

Он нуждается в некотором переформатировании, чтобы скомпилировать в текущие версии Linux / glibc, но все еще работает.

Жулиано
источник
1
Исключительно круто.
ojrac
16

Когда процесс начинается, STDIN, STDOUT и STDERR подключаются к чему-либо . Как правило, вы не можете изменить это после запуска команды. В случае, если вы описываете, это, вероятно, tty, связанный с сессией ssh. nohup в значительной степени просто делает ...

command < /dev/null > nohup.out 2>&1

То есть устанавливает STDIN в / dev / null, STDOUT в файл и STDERR в STDOUT. Экран делает гораздо более сложные вещи, включая настройку ttys, которые направлены на себя.

Я не знаю ни одного способа задним числом nohup или скрининга запущенного процесса. Если вы перейдете в / proc / $ pid / fd и увидите, на что указывают 0, 1 и 2.

Вы можете испытать удачу с отречением, но не в том случае, если процесс пытается что-либо сделать с STDIN, STDOUT или STDERR.

Freiheit
источник
2
+1 за хорошие комментарии. st (din | out | err) - другая половина проблемы, и я ценю совет о том, где начать искать, когда я в следующий раз буду в этой пробке.
ojrac
6
Вы на самом деле можете изменить это в большинстве Unixes. Это отвратительный хак. Я люблю это. :) Что вы делаете, подключаетесь к процессу, используя поддержку отладки, такую ​​как ptrace, а затем заставляете процесс вызывать dup2 () для повторного подключения 0,1,2 к другому дескриптору файла.
Zan Lynx
2
да, вы можете изменить это. Включает приостановку процесса (SIGSTOP) и изменение файловых дескрипторов для fd 0, 1, 2. Затем перезапуск (SIGCONT).
Майкл Мартинес
13

Cryopid - это дальнейшее развитие от автора grab.c, который замораживает процесс в файл, который вы затем запускаете (внутри экрана), чтобы возобновить процесс.

TRS-80
источник
1
Приятно! Я пытался использовать криопид в своей магистерской диссертации о миграции процессов, но он не работал постоянно, независимо от того, что я делал. В конце концов, мне пришлось использовать dynckpt с древней версией Linux. Возможно, вы участвуете в разработке криопида? Я вижу, что ваше имя похоже на домен автора.
Джулиано
1
Я не участвую в разработке, я просто знаю автора из университета. У него нет времени, чтобы поддерживать криопид в данный момент, поэтому похоже, что некоторые люди начали работать над ним на shareource.org/project/cryopid
TRS-80
12

Я могу только дать вам простое «Нет» без объяснения, почему для экранной части я бы сам был заинтересован в причине.

Однако вы пробовали disown(встроенный Bash)

~ $ echo $SHELL
/bin/bash
~ $ type disown
disown is a shell builtin
~ $ help disown
disown: disown [-h] [-ar] [jobspec ...]
     By default, removes each JOBSPEC argument from the table of active jobs.
    If the -h option is given, the job is not removed from the table, but is
    marked so that SIGHUP is not sent to the job if the shell receives a
    SIGHUP.  The -a option, when JOBSPEC is not supplied, means to remove all
    jobs from the job table; the -r option means to remove only running jobs.
serverhorror
источник
5

Недавно я увидел ссылку на neercs , похожую на экран утилиту, созданную с использованием libcaca, библиотеки цветов ascii-art. Среди других функций, он может похвастаться возможностью захватить существующий процесс и переопределить его внутри сеанса neercs (экран).

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

Дэниел Лоусон
источник
2

Я, вероятно, недооцениваю это, так что не стесняйтесь поправлять меня (я уже узнал об отречении!) ... Не сработали бы ctrl-Z и "bg", чтобы хотя бы запустить процесс в фоновом режиме? Или это ключевой вопрос, который вы все еще хотели бы видеть в STDOUT во время его работы?

Chris_K
источник
1
Это все равно убило бы процесс, когда владелец tty умирает, поэтому оператору нужно покинуть ящик, где он инициировал выполнение команды, чего он хочет избежать
serverhorror
Хорошо, я куплю это. Спасибо за объяснение. Так что предложения отречься -h наверняка выглядят намного умнее, чем у меня :-)
Chris_K
1
Вы все еще можете сделать это, только после того, как вам придется отречься от -h: stackoverflow.com/a/625436/705198
AndrewPK
2

Если вы можете жить, не имея возможности взаимодействовать с процессом, и не возражаете против загрузки случайных модулей ядра, вы можете сделать хуже, чем смотреть на Snoop . Кроме того, есть несколько других проектов. Вот один вызов injcode, который в основном может делать то, что вы хотите.

Дэвид Пашли
источник
2

Вы можете перенаправить вывод процесса в файл с помощью GDB

https://blog-en.openalfa.com/how-to-detach-from-the-terminal-a-running-process-in-linux

а затем отречься от него

Upd: мне пришлось запустить gdb с помощью sudo и немного другой команды gdb в Ubuntu 18.04:

p (int)dup2(open("/tmp/test.stdout", 1), 1)

d9k
источник
Отличное использование GDB, спасибо!
ojrac
1

Я хотел использовать nohup(или подобное), чтобы запустить linksбраузер командной строки и присоединить к нему после загрузки файла с веб-сайта ASP.NET со сложным процессом аутентификации и большим количеством скрытого состояния просмотра, что затрудняло использование для выполнения работы с curl/ wget.

Я, наконец, закончил тем, что использовал tmuxработу, которая отлично справилась:

  1. Бегать tmux
  2. Запустите ваше приложение ( linksв моем случае) и оставьте его запущенным
  3. Закройте сеанс SSH, приложение останется запущенным
  4. Подключитесь с помощью SSH к той же машине позже и запустите, tmux attachчтобы вернуть приложение на экран
Дмитрий Гусев
источник
tmux хорош - но, как nohup или screen, он работает только в том случае, если вы используете его перед запуском процесса. Этот вопрос о случаях, когда вы понимаете, что вам нужен tmux после того, как ваш процесс уже запущен.
ojrac
-1

Это то, что вы беспокоитесь о времени ожидания сессии? В этом случае вы можете нажать Ctrl-z и bg процесса, а затем просто положить что-нибудь, чтобы сохранить сеанс, как "ping -t localhost" или "top".

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

TrojanName
источник
Это выход из системы.
ojrac
1
Еще один способ остановить отключение - запустить наверх. Это всегда тасует несколько байтов.
Рори