Для тех, кто сталкивается с той же проблемой: помните, что даже если вы печатаете, yourExecutable &и выходы продолжают появляться на экране и Ctrl+C, кажется, ничего не останавливает, просто печатайте вслепую disown;и нажимайте, Enterдаже если экран прокручивается с выходами, и вы не видите ты печатаешь Процесс будет остановлен, и вы сможете закрыть терминал без его остановки.
Nav
Ответы:
1367
Использование Job Control в bash для отправки процесса в фоновый режим:
Ctrl+ Zостановить (приостановить) программу и вернуться в оболочку.
bg запустить его в фоновом режиме.
disown -h [job-spec]где [job-spec] - номер задания (как %1для первого запущенного задания; узнайте о вашем номере с помощью jobsкоманды), чтобы задание не было убито при закрытии терминала.
Поскольку вопрос заключался в том, как «поместить его в nohup», disown -hвозможно, более точный ответ: «заставить disown вести себя больше как nohup (то есть задания будут оставаться в дереве процессов вашей текущей оболочки до тех пор, пока вы не выйдете из нее). Это позволяет увидеть все работы, которые начались этой оболочкой ". (из [ quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/… )
д-р Ян-Филипп Герке
8
Как мне восстановить работу позже? Я вижу, как он работает, используя ps -e.
Пауло Касаретто
26
Вы не можете видеть выходные данные задания после того, как disown, disown делает процесс демоном, что означает, что стандартный ввод / вывод перенаправляется в / dev / null. Итак, если вы планируете отказаться от работы, лучше начать ее с входа в файл, напримерmy_job_command | tee my_job.log
rustyx
8
Можно ли как-то сделать что-то вроде 'my_job_command | tee my_job.log ' после того, как команда уже запущена?
возник
23
disownотделяет любые трубы от процесса. Для подсоединения труб используйте, gdbкак описано в этой теме . Более конкретно этот пост .
mbrownnyc
185
Предположим, по какой-то причине Ctrl+ Zтоже не работает, перейдите на другой терминал, найдите идентификатор процесса (используя ps) и запустите:
kill -SIGSTOP PID
kill -SIGCONT PID
SIGSTOPприостановит процесс и SIGCONTвозобновит процесс в фоновом режиме. Теперь закрытие обоих терминалов не остановит ваш процесс.
Да, это проблема ОС, kill не работает с Cygwin в Windows.
Pungs
6
Также очень полезно, если задание запускается из другого сеанса SSH.
Амир Али Акбари
5
Просто не забудьте сделать disown %1в первом терминале, прежде чем закрывать его.
Фред
1
Это полезно, поскольку я запустил графический интерфейс с консолью (в моем случае я запустился с konsole kwinпосле сбоя, не задумываясь о последствиях). Так что, если бы я остановил Kwin, все бы заморозилось, и у меня не было возможности бежать bg!
Мишель
@fred Я этого не делал, и казалось, что он продолжает работать. Возможно или я нажал не тот PID?
Никто
91
Команда для отделения запущенного задания от оболочки (= делает его nohup) является disownи основной командой оболочки.
Из man-страницы bash (man bash):
отречься [-ar] [-h] [задание на работу ...]
Без параметров каждая спецификация заданий удаляется из таблицы активных заданий. Если указана опция -h, каждая спецификация заданий не удаляется из таблицы, а помечается так, что SIGHUP не отправляется заданию, если оболочка получает SIGHUP. Если спецификация заданий отсутствует и не указана ни опция -a, ни опция -r, используется текущее задание. Если спецификация заданий не указана, опция -a означает удалить или отметить все задания; опция -r без аргумента jobspec ограничивает выполнение операций заданиями. Возвращаемое значение равно 0, если в задании не указано допустимое задание.
Это означает, что простой
disown -a
удалит все задания из таблицы заданий и сделает их нету
disown -aудаляет все задания Простое disownудаляет только текущую работу. Как говорится в справочной странице в ответе.
Руна Шеллеруп Философ
73
Это хорошие ответы выше, я просто хотел добавить пояснение:
Вы не можете disownпид или процесс, вы disownработа, и это важное различие.
Задание - это то, что является понятием процесса, прикрепленного к оболочке, поэтому вы должны выбросить задание в фоновый режим (не приостанавливать его), а затем отказаться от него.
Выпуск:
% jobs
[1] running java
[2] suspended vi
% disown %1
Только для AIXа Solaris. «Версии nohup в AIX и Solaris имеют опцию -p, которая изменяет запущенный процесс, игнорируя будущие сигналы SIGHUP. В отличие от описанного выше встроенного в bash disown, nohup -p принимает идентификаторы процессов». Источник
АликЭльзин-килака
27
Ответ Node действительно хорош, но он оставил открытым вопрос, как перенаправить 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)
$1 =0
Close (1) возвращает ноль в случае успеха.
(gdb) call open("loop.out",01102,0600)
$6 =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("")выводит сообщение об ошибке. Если нам нужна ошибка, используйте команду p errnogdb.
Теперь мы можем проверить вновь перенаправленный файл. /usr/sbin/lsof -p <PID>печатает:
Если мы хотим, мы можем перенаправить 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>011: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>011:16 pts/36 S 0:00/bin/bash ./loop.sh
И теперь мы можем выйти из вызывающего bash. Процесс продолжается в фоновом режиме. Если мы выйдем, его PPID станет 1 (процесс init (1)), а управляющий терминал станет неизвестным.
$ ps -f <PID>
UID PID PPID C STIME TTY STAT TIME CMD
<UID><PID>1011:16? S 0:00/bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>...
loop.sh <PID> truey 0u CHR 136,3638/dev/pts/36(deleted)
loop.sh <PID> truey 1u REG 0,26112715008411/home/truey/loop.out
loop.sh <PID> truey 2u CHR 136,3638/dev/pts/36(deleted)
КОММЕНТАРИЙ
Материал gdb можно автоматизировать, создав файл (например, loop.gdb), содержащий команды и запустив его gdb -q -x loop.gdb -p <PID>. Мой loop.gdb выглядит так:
Действительно очень информативно и, вероятно, будет хорошо работать в простых случаях. Но будьте осторожны, более сложные случаи могут с треском провалиться. У меня был один из них сегодня: мой процесс породил другой процесс, который сделал вывод (предположительно для stderr), но подключил stdout для связи со своим хозяином. Перенаправление основных FD хозяев было безрезультатным, потому что дочерний процесс унаследовал stderr, а закрытие дочернего стандартного вывода не удалось запустить мастер, ожидающий на другом конце канала. Х- | Лучше знать ваши процессы, прежде чем вы попробуете это.
cmaster - восстановить монику
@cmaster Вы можете проверить, перенаправлен ли дескриптор с помощью lsof(имя дескриптора файла pipe, а не как /dev/pts/1) или с помощью ls -l /proc/<PID>/fd/<fd>(это показывает символическую ссылку на дескриптор). Также подпроцессы все еще могут иметь не перенаправленные выходные данные, которые должны быть перенаправлены в файл.
Ctrl+ Zостановить (приостановить) программу и вернуться в оболочку.
bg запустить его в фоновом режиме.
disown -h так что процесс не будет убит при закрытии терминала.
Напечатайте, exitчтобы выйти из оболочки, потому что теперь все готово, поскольку операция будет выполняться в фоновом режиме в своем собственном процессе, поэтому она не привязана к оболочке.
Этот процесс эквивалентен запуску nohup SOMECOMMAND.
Это сработало хорошо. Он продолжал запускать мой процесс даже после закрытия окон терминала. В качестве оболочки по умолчанию используется ksh, поэтому команды bgand disownне работают.
Я думаю, что поведение для отречения-а заключается в том, чтобы сократить привязанность ко всем заданиям. Тем не менее, он не отключает конвейеры stdin / stdout, что означает, что процесс все равно будет пытаться писать (/ читать) из терминала
Kelthar
-2
Это работало для меня на Ubuntu Linux в то время как в Tcshell.
yourExecutable &
и выходы продолжают появляться на экране иCtrl+C
, кажется, ничего не останавливает, просто печатайте вслепуюdisown;
и нажимайте,Enter
даже если экран прокручивается с выходами, и вы не видите ты печатаешь Процесс будет остановлен, и вы сможете закрыть терминал без его остановки.Ответы:
Использование Job Control в bash для отправки процесса в фоновый режим:
bg
запустить его в фоновом режиме.disown -h [job-spec]
где [job-spec] - номер задания (как%1
для первого запущенного задания; узнайте о вашем номере с помощьюjobs
команды), чтобы задание не было убито при закрытии терминала.источник
disown -h
возможно, более точный ответ: «заставить disown вести себя больше как nohup (то есть задания будут оставаться в дереве процессов вашей текущей оболочки до тех пор, пока вы не выйдете из нее). Это позволяет увидеть все работы, которые начались этой оболочкой ". (из [ quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/… )disown
, disown делает процесс демоном, что означает, что стандартный ввод / вывод перенаправляется в / dev / null. Итак, если вы планируете отказаться от работы, лучше начать ее с входа в файл, напримерmy_job_command | tee my_job.log
disown
отделяет любые трубы от процесса. Для подсоединения труб используйте,gdb
как описано в этой теме . Более конкретно этот пост .Предположим, по какой-то причине Ctrl+ Zтоже не работает, перейдите на другой терминал, найдите идентификатор процесса (используя
ps
) и запустите:SIGSTOP
приостановит процесс иSIGCONT
возобновит процесс в фоновом режиме. Теперь закрытие обоих терминалов не остановит ваш процесс.источник
disown %1
в первом терминале, прежде чем закрывать его.kwin
после сбоя, не задумываясь о последствиях). Так что, если бы я остановил Kwin, все бы заморозилось, и у меня не было возможности бежатьbg
!Команда для отделения запущенного задания от оболочки (= делает его nohup) является
disown
и основной командой оболочки.Из man-страницы bash (man bash):
Это означает, что простой
удалит все задания из таблицы заданий и сделает их нету
источник
disown -a
удаляет все задания Простоеdisown
удаляет только текущую работу. Как говорится в справочной странице в ответе.Это хорошие ответы выше, я просто хотел добавить пояснение:
Вы не можете
disown
пид или процесс, выdisown
работа, и это важное различие.Задание - это то, что является понятием процесса, прикрепленного к оболочке, поэтому вы должны выбросить задание в фоновый режим (не приостанавливать его), а затем отказаться от него.
Выпуск:
См. Http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/ для более подробного обсуждения Unix Job Control.
источник
К сожалению,
disown
это специфично для bash и доступно не во всех оболочках.Некоторые разновидности Unix (например, AIX и Solaris) имеют параметр для самой
nohup
команды, который можно применить к запущенному процессу:Смотрите http://en.wikipedia.org/wiki/Nohup
источник
AIX
аSolaris
. «Версии nohup в AIX и Solaris имеют опцию -p, которая изменяет запущенный процесс, игнорируя будущие сигналы SIGHUP. В отличие от описанного выше встроенного в bash disown, nohup -p принимает идентификаторы процессов». ИсточникОтвет Node действительно хорош, но он оставил открытым вопрос, как перенаправить stdout и stderr. Я нашел решение для Unix и Linux , но оно также не завершено. Я хотел бы объединить эти два решения. Вот:
Для своего теста я создал небольшой скрипт bash, называемый loop.sh, который печатает pid самого себя с минутным сном в бесконечном цикле.
Теперь получите PID этого процесса как-то. Обычно
ps -C loop.sh
это достаточно хорошо, но это напечатано в моем случае.Теперь мы можем переключиться на другой терминал (или нажать ^ Z и на том же терминале). Теперь
gdb
следует присоединиться к этому процессу.Это останавливает скрипт (если запущен). Его состояние может быть проверено
ps -f <PID>
, гдеSTAT
поле 'T +' (или в случае ^ Z 'T'), что означает (man ps (1))Close (1) возвращает ноль в случае успеха.
Open (1) возвращает новый дескриптор файла в случае успеха.
Этот открытый равен с
open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)
. ВместоO_RDWR
O_WRONLY
может применяться, но/usr/sbin/lsof
говорит 'u' для всех обработчиков файлов std * (FD
столбец), чтоO_RDWR
.Я проверил значения в файле заголовка /usr/include/bits/fcntl.h.
Выходной файл может быть открыт с помощью
O_APPEND
, какnohup
было бы, но это не предлагаетсяman open(2)
, из-за возможных проблем NFS.Если мы получим -1 как возвращаемое значение, то
call perror("")
выводит сообщение об ошибке. Если нам нужна ошибка, используйте командуp errno
gdb.Теперь мы можем проверить вновь перенаправленный файл.
/usr/sbin/lsof -p <PID>
печатает:Если мы хотим, мы можем перенаправить stderr в другой файл, если мы хотим использовать
call close(2)
иcall open(...)
снова, используя другое имя файла.Теперь прикрепленное
bash
должно быть освобождено, и мы можем выйтиgdb
:Если скрипт был остановлен
gdb
с другого терминала, он продолжает работать. Мы можем переключиться обратно на терминал loop.sh. Теперь он ничего не пишет на экран, а работает и пишет в файл. Мы должны поставить его на задний план. Так что жми^Z
.(Теперь мы находимся в том же состоянии, как если бы мы
^Z
были нажаты в начале.)Теперь мы можем проверить состояние работы:
Поэтому процесс должен работать в фоновом режиме и отключаться от терминала. Число в
jobs
выводе команды в квадратных скобках обозначает задание внутриbash
. Мы можем использовать в следующих встроенныхbash
командах применение знака «%» перед номером задания:И теперь мы можем выйти из вызывающего bash. Процесс продолжается в фоновом режиме. Если мы выйдем, его PPID станет 1 (процесс init (1)), а управляющий терминал станет неизвестным.
КОММЕНТАРИЙ
Материал gdb можно автоматизировать, создав файл (например, loop.gdb), содержащий команды и запустив его
gdb -q -x loop.gdb -p <PID>
. Мой loop.gdb выглядит так:Или вместо этого можно использовать следующий вкладыш:
Я надеюсь, что это довольно полное описание решения.
источник
lsof
(имя дескриптора файлаpipe
, а не как/dev/pts/1
) или с помощьюls -l /proc/<PID>/fd/<fd>
(это показывает символическую ссылку на дескриптор). Также подпроцессы все еще могут иметь не перенаправленные выходные данные, которые должны быть перенаправлены в файл.Чтобы отправить запущенный процесс в nohup ( http://en.wikipedia.org/wiki/Nohup )
nohup -p pid
у меня не получилосьЗатем я попробовал следующие команды, и это работало очень хорошо
Запустите SOMECOMMAND, скажем
/usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1
.Ctrl+ Zостановить (приостановить) программу и вернуться в оболочку.
bg
запустить его в фоновом режиме.disown -h
так что процесс не будет убит при закрытии терминала.Напечатайте,
exit
чтобы выйти из оболочки, потому что теперь все готово, поскольку операция будет выполняться в фоновом режиме в своем собственном процессе, поэтому она не привязана к оболочке.Этот процесс эквивалентен запуску
nohup SOMECOMMAND
.источник
В моей системе AIX я пытался
Это сработало хорошо. Он продолжал запускать мой процесс даже после закрытия окон терминала. В качестве оболочки по умолчанию используется ksh, поэтому команды
bg
anddisown
не работают.источник
bg
- это переведет задание в фоновый режим и вернется в рабочий процессdisown -a
- это отрежет все вложения с заданием (так что вы можете закрыть терминал, и он все еще будет работать)Эти простые шаги позволят вам закрыть терминал, продолжая процесс.
Он не наденет
nohup
(исходя из моего понимания вашего вопроса, он вам здесь не нужен).источник
Это работало для меня на Ubuntu Linux в то время как в Tcshell.
CtrlZ приостановить это
bg
бежать в фоновом режимеjobs
чтобы получить свой номер работыnohup %n
где n - номер работыисточник
nohup: failed to run command '%1': No such file or directory