Как поместить уже запущенный процесс под nohup?



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



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

534   10  

10 ответов:

С помощью Контрольная Работа из bash, чтобы отправить процесс в фоновом режиме:

  1. Ctrl+Z чтобы остановить (приостановить) программу и вернуться в оболочку.
  2. bg, чтобы запустить его в фоновом режиме.
  3. disown -h [job-spec] где [job-spec] - номер задания (например %1 для первого запущенного задания; найдите свой номер с помощью jobs команда), чтобы задание не было убито, когда терминал закрывается.

предположим, что по какой-то причине Ctrl+Z также не работает, перейдите на другой терминал, найдите идентификатор процесса (используя ps) и запустите:

kill -20 PID 
kill -18 PID

kill -20 (SIGTSTP) приостановит процесс и kill -18 (SIGCONT) возобновит процесс, в фоновом режиме. Так что теперь закрытие обоих ваших терминалов не остановит ваш процесс.

команда для отделения запущенного задания от оболочки (= делает его nohup) является disown и базовая команда оболочки.

от bash-manpage (man bash):

откреститься [- ar] [- h] [jobspec ...]

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

это значит, что простой

disown -a

удалит все задания из таблицы заданий и сделает их nohup

Это хорошие ответы выше, я просто хотел добавить уточнение:

нельзя disown пид или процесс, вы disown работа, и это важное различие.

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

вопрос:

%  jobs
[1]  running java 
[2]  suspended vi
%  disown %1

посмотреть http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/ для более подробного обсуждения управления заданиями Unix.

к сожалению disown специфичен для bash и доступен не во всех оболочках.

некоторые ароматы Unix (например, AIX и Solaris) имеют опцию на nohup сама команда, которая может быть применена к запущенному процессу:

nohup -p pid

см.http://en.wikipedia.org/wiki/Nohup

ответ узла действительно велик, но он оставил открытым вопрос, как можно перенаправить stdout и stderr. Я нашел решение на Unix & Linux, но он также не является полным. Я хотел бы объединить эти два решения. Вот это:

для моего теста я сделал небольшой скрипт bash под названием loop.sh, который печатает pid самого себя с минутным сном в бесконечном цикле.

$./loop.sh

теперь получить PID этого процесса каким-то образом. Обычно ps -C loop.sh - это хорошо достаточно, но он напечатан в моем случае.

теперь мы можем переключиться на другой терминал (или нажать ^Z и в тот же терминал). Сейчас gdb должны быть присоединены к этому процессу.

$ gdb -p <PID>

это останавливает скрипт (если он запущен). Его состояние можно проверить с помощью ps -f <PID>, где STAT поле ' T+ '(или в случае ^Z 'T'), что означает (man ps(1))

    T Stopped, either by a job control signal or because it is being traced
    + is in the foreground process group

(gdb) call close(1)
 = 0

Close(1) возвращает ноль при успешном выполнении.

(gdb) call open("loop.out", 01102, 0600)
 = 1

Open (1) возвращает новый файл дескриптор в случае успеха.

это открытие равно с open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR). Вместо O_RDWRO_WRONLY можно применить, но /usr/sbin/lsof говорит ' u ' для всех обработчиков std * файлов (FD столбец), которая составляет O_RDWR.

я проверил значения в /usr/include/bits / fcntl.H заголовочный файл.

выходной файл можно открыть с помощью O_APPEND, а nohup сделал бы, но это не предлагали man open(2), из-за возможных проблем с NFS.

если мы получим -1 в качестве возвращаемого значения, то call perror("") выводит сообщение об ошибке. Если нам нужен errno, используйте p errno gdb comand.

теперь мы можем проверить вновь перенаправлены файл. /usr/sbin/lsof -p <PID> принты:

loop.sh <PID> truey    1u   REG   0,26        0 15008411 /home/truey/loop.out

если мы хотим, мы можем перенаправить stderr в другой файл, если мы хотим использовать call close(2) и call open(...) еще раз, используя другое имя файла.

теперь прилагается bash должен быть освобожден, и мы можем бросить gdb:

(gdb) detach
Detaching from program: /bin/bash, process <PID>
(gdb) q

если скрипт был остановлен gdb из другого терминала он продолжает работать. Мы можем переключиться обратно loop.sh-это терминал. Теперь он ничего не записывает на экран, но работает и записывает в файл. Мы должны отодвинуть это на задний план. Так что нажмите ^Z.

^Z
[1]+  Stopped                 ./loop.sh

(сейчас мы находимся в том же состоянии, как если ^Z был нажат в начале.)

теперь мы можем проверить состояние задания:

$ ps -f 24522
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID><PPID>  0 11:16 pts/36   S      0:00 /bin/bash ./loop.sh
$ jobs
[1]+  Stopped                 ./loop.sh

поэтому процесс должен быть запущен в фоновом режиме и отделен от терминал. Число в jobs вывод команды в квадратных скобках определяет задание внутри bash. Мы можем использовать в следующем встроенный bash команды, применяющие знак " % " перед номером задания:

$ bg %1
[1]+ ./loop.sh &
$ disown -h %1
$ ps -f <PID>
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID><PPID>  0 11:16 pts/36   S      0:00 /bin/bash ./loop.sh

и теперь мы можем выйти из вызывающей Баш. Процесс продолжает работать в фоновом режиме. Если мы выйдем из его PPID стать 1(init (1) процесс) и терминал управления стать неизвестный.

$ ps -f <PID>
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID>     1  0 11:16 ?        S      0:00 /bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>
...
loop.sh <PID> truey    0u   CHR 136,36                38 /dev/pts/36 (deleted)
loop.sh <PID> truey    1u   REG   0,26     1127 15008411 /home/truey/loop.out
loop.sh <PID> truey    2u   CHR 136,36                38 /dev/pts/36 (deleted)

комментарий

материал gdb может быть автоматизирован, создавая файл (например, цикл.gdb) содержащий команды и run gdb -q -x loop.gdb -p <PID>. Моя петля.gdb выглядит так:

call close(1)
call open("loop.out", 01102, 0600)
# call close(2)
# call open("loop.err", 01102, 0600)
detach
quit

или можно использовать следующий один лайнер вместо:

gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID>

я надеюсь, что это довольно полное описание решения.

для отправки запущенного процесса в nohup (http://en.wikipedia.org/wiki/Nohup)

nohup -p pid, Это не сработало для меня

затем я попробовал следующие команды, и это сработало очень хорошо

  1. выполнить некоторые SOMECOMMAND, скажи /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1.

  2. Ctrl+Z чтобы остановить (приостановить) программу и вернуться в оболочку.

  3. bg, чтобы запустить его в фон.

  4. disown -h чтобы процесс не был убит, когда терминал закрывается.

  5. тип exit выйти из оболочки, потому что теперь вы хорошо идти, как операция будет выполняться в фоновом режиме в своем собственном процессе, поэтому он не привязан к оболочке.

этот процесс эквивалентен запуску nohup SOMECOMMAND.

на моей системе AIX, я пытался

nohup -p  processid>

он работал хорошо. Он продолжал запускать мой процесс даже после закрытия окон терминала. У нас есть KSH в качестве оболочки по умолчанию, поэтому bg и disown команды не работают.

  1. ctrl + z - это приостановит работу (не собирается отменять!)
  2. bg - это поставит задание в фоновом режиме и вернуться в запущенном процессе
  3. disown -a - это вырезать все вложения с работы (так что вы можете закрыть терминал и он все равно будет работать)

эти простые шаги позволят вам закрыть терминал, сохраняя процесс работает.

он не надел nohup (исходя из моих понимание вашего вопроса, вам это не нужно здесь).

это работало для меня на Ubuntu linux в то время как в tcshell.

  1. CtrlZ приостановить

  2. bg на

  3. jobs чтобы получить свой номер задания

  4. nohup %n где N-номер задания

Comments

    Ничего не найдено.