Відповіді:
Використання керування роботою bash для надсилання процесу на задній план:
bg
запустити його у фоновому режимі.disown -h [job-spec]
де [job-spec] - номер завдання (як %1
для першого запущеного завдання; знайдіть про свій номер за допомогою jobs
команди), щоб завдання не загинуло, коли термінал закривається.disown -h
можливо, є більш точна відповідь: "змусити відхреститися поводитись більше, як нохуп (тобто завдання залишатимуться у вашому поточному дереві обробки оболонки до виходу з оболонки). Це дозволяє вам побачити усі завдання, які розпочала ця оболонка ". (від [ quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/… )
disown
, відключення робить процес демон, а це означає, що стандартні введення / виведення перенаправляються на / dev / null. Отже, якщо ви плануєте відмовитись від роботи, краще розпочати її з входу у файл, наприкладmy_job_command | tee my_job.log
disown
відключає будь-які труби від процесу. Для повторного приєднання труб використовуйте, gdb
як описано в цій нитці . Більш конкретно, це повідомлення .
Припустимо, чомусь Ctrl+ Zтеж не працює, перейдіть до іншого терміналу, знайдіть ідентифікатор процесу (використовуючи ps
) та запустіть:
kill -SIGSTOP PID
kill -SIGCONT PID
SIGSTOP
призупинить процес і SIGCONT
відновить процес у фоновому режимі. Тож закриття обох терміналів не зупинить ваш процес.
disown %1
в першому терміналі, перш ніж закривати його.
kwin
після аварії, не думаючи про наслідки). Тож якби я зупинив kwin, усе б замерзло і я не мав би можливості бігати bg
!
Команда відокремити запущене завдання від оболонки (= робить його nohup) є disown
базовою командою shell.
З bash-manpage (man bash):
відрікся [-ar] [-h] [jobspec ...]
Без опцій кожен спецзапис видаляється з таблиці активних завдань. Якщо параметр -h заданий, кожен параметр jobs не видаляється з таблиці, але позначається таким чином, що SIGHUP не надсилається до завдання, якщо оболонка отримує SIGHUP. Якщо немає робочих параметрів, і не надається опція -a, або -r, використовується поточне завдання. Якщо не вказано жодного робочого місця, опція -a означає видалити або позначити всі завдання; опція -r без аргументу jobspec обмежує роботу запущеними завданнями. Повернене значення дорівнює 0, якщо у специфікації jobs не вказано дійсне завдання.
Це означає, що простий
disown -a
видалить усі завдання з таблиці завдань і зробить їх відсутніми
disown -a
видаляє всі завдання. Простий disown
лише видаляє поточну роботу. Як говорить сторінка людини у відповіді.
Це хороші відповіді вище, я просто хотів додати уточнення:
Ви не 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
AIX
і Solaris
. "AIX і Solaris версії nohup мають опцію -p, яка модифікує запущений процес, щоб ігнорувати майбутні сигнали SIGHUP. На відміну від вищеописаного відключення, побудованого в bash, nohup -p приймає ідентифікатори процесу." Джерело
Відповідь Вузла дійсно чудова, але вона залишила відкритим питання про те, як можна перенаправити stdout та stderr. Я знайшов рішення на Unix & Linux , але воно також не є повним. Я хотів би об'єднати ці два рішення. Ось:
Для мого тесту я створив невеликий скрипт bash під назвою loop.sh, який друкує під себе під час хвилинного сну у нескінченному циклі.
$./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
Закрити (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_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("")
надрукуємо повідомлення про помилку. Якщо нам потрібна 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 можна автоматизувати, створивши файл (наприклад, loop.gdb), що містить команди та запустити gdb -q -x loop.gdb -p <PID>
. Мій loop.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>
Я сподіваюся, що це досить повний опис рішення.
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
.
bg
- це поставить завдання на другий план і повернеться в запущений процесdisown -a
- це скоротить усе вкладення з роботою (так що ви можете закрити термінал, і він все ще буде працювати)Ці прості дії дозволять вам закрити термінал, зберігаючи процес.
Це не буде покладене nohup
(на основі мого розуміння вашого питання, вам це не потрібно тут).
Це працювало для мене на Ubuntu linux під час роботи в tcshell.
CtrlZ призупинити його
bg
бігати у фоновому режимі
jobs
щоб отримати його номер роботи
nohup %n
де n - номер роботи
nohup: failed to run command '%1': No such file or directory
yourExecutable &
і виходи продовжують надходити на екран іCtrl+C
, здається, нічого не зупиняють, просто сліпо введітьdisown;
і натисніть,Enter
навіть якщо екран прокручується з виходами, і ви не бачите, що ти друкуєш. Процес буде відмовлено, і ви зможете закрити термінал, не вмираючи.