2008-11-12 10 views
262

Я работаю на Linux-машине через SSH (Putty). Мне нужно оставить процесс, работающий в течение ночи, поэтому я подумал, что могу сделать это, запустив процесс в фоновом режиме (с амперсандом в конце команды) и перенаправляя stdout в файл. К моему удивлению, это не работает. Как только я закрываю окно Putty, процесс останавливается.Linux: предотвращение остановки фонового процесса после закрытия SSH-клиента

Как я могу предотвратить это? ???

ответ

281

Проверьте программу "nohup".

+4

Как вы его остановите? – 2010-07-13 17:49:12

+9

Войдите и выполните «kill ». Используйте «pidof», если вы не знаете pid. – JesperE 2010-07-13 18:01:22

+26

Вы можете использовать `nohup command>/dev/null 2> & 1 &` для запуска в фоновом режиме без создания каких-либо выходов stdout или stderr (без файла `nohup.out`) – KCD 2013-04-01 23:03:28

157

Я бы рекомендовал использовать GNU Screen. Это позволяет вам отключиться от сервера, пока все ваши процессы продолжают работать. Я не знаю, как я жил без него, прежде чем знал, что он существует.

+7

Это одна из самых больших программных продуктов, которые я когда-либо использовал. Шутки в сторону. У меня он работает на BSD-боксе, в который я вставляю ssh из EVERYWHERE, и могу просто повторно подключиться к моему экрану и иметь все мои терминалы, где я делаю всевозможные вещи. – 2008-11-12 20:02:40

+1

Я могу подтвердить это. Экран - отличное приложение. Возможность повторного прикрепления удивительна и экономит много потенциально потерянной работы. – willasaywhat 2008-11-12 21:06:48

75

Когда сеанс закрыт, процесс получает сигнал SIGHUP, который, по-видимому, не захватывает. Вы можете использовать команду nohup при запуске процесса или Баша встроенных команд disown -h после начала процесса, чтобы предотвратить это:

> 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. 
33
nohup blah & 

Подставьте имя процесса для бла!

5

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

nohup /bin/sh -c "echo \$\$ > $pidfile; exec $FOO_BIN $FOO_CONFIG " > /dev/null 

поЬир делает процесс вы начинаете невосприимчивы к завершению которой ваш SSH сессия и его дочерние процессы убивает на вас выход из системы. Команда, которую я дал, предоставляет вам способ хранения pid приложения в файле pid, чтобы вы могли впоследствии его убить позже и разрешить запуск процесса после того, как вы вышли из системы.

11

Как уже отмечалось, для запуска процесса в фоновом режиме, так что вы можете отключиться от сеанса SSH, вам необходимо, чтобы фоновый процесс должным образом отсоединился от его управляющего терминала - это псевдо-tty, что SSH сеанс использует.

Вы можете найти информацию о процессах демонализации в таких книгах, как «Расширенная сетевая программа» Стивена, Том 1, 3-й Эдн или «Расширенное программирование Unix» Рочкинда.

Мне недавно (за последние пару лет) пришлось иметь дело с непокорной программой, которая не демонанизировала себя должным образом. В конце концов я столкнулся с этим, создав общую демонизирующую программу - похожую на nohup, но с большим количеством доступных элементов управления.

Usage: daemonize [-abchptxV][-d dir][-e err][-i in][-o out][-s sigs][-k fds][-m umask] -- command [args...] 
    -V   print version and exit 
    -a   output files in append mode (O_APPEND) 
    -b   both output and error go to output file 
    -c   create output files (O_CREAT) 
    -d dir  change to given directory 
    -e file  error file (standard error - /dev/null) 
    -h   print help and exit 
    -i file  input file (standard input - /dev/null) 
    -k fd-list keep file descriptors listed open 
    -m umask set umask (octal) 
    -o file  output file (standard output - /dev/null) 
    -s sig-list ignore signal numbers 
    -t   truncate output files (O_TRUNC) 
    -p   print daemon PID on original stdout 
    -x   output files must be new (O_EXCL) 

Двойная тире является необязательной для систем, не использующих функцию GNU getopt(); необходимо (или вы должны указать POSIXLY_CORRECT в среде) на Linux и т. д. Поскольку двунаправленная работа работает везде, лучше всего использовать ее.

Вы все еще можете связаться со мной (имя первого имени точки в gmail dot com), если вы хотите, чтобы источник для daemonize.

Однако код теперь (наконец) доступен на GitHub в моих SOQ (Stack Переливные Вопросы) вместилище как файл daemonize-1.10.tgz в packages подкаталоге.

4

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

Если этот процесс необходимо регулярно запускать, и у вас есть достаточный доступ на сервер, лучшим вариантом будет использование cron для запуска задания. Вы также можете использовать init.d (супер демона), чтобы начать свой процесс в фоновом режиме, и он может прекратиться, как только это будет сделано.

16

Лично мне нравится команда «batch».

$ batch 
> mycommand -x arg1 -y arg2 -z arg3 
> ^D 

Этот материал находится на заднем плане, а затем отправляет вам результаты. Это часть cron.

1

Если вы также хотите использовать X-приложения, используйте xpra вместе с «экраном».

32

daemonize? поЬир? SCREEN? (tmux ftw, screen is ununk ;-)

Просто делайте то, что делали все другие приложения с самого начала - двойная вилка.

# ((exec sleep 30)&) 
# grep PPid /proc/`pgrep sleep`/status 
PPid: 1 
# jobs 
# disown 
bash: disown: current: no such job 

Bang! Выполнено :-) Я использовал это бесчисленное количество раз для всех типов приложений и многих старых машин. Вы можете комбинировать с переадресацией и еще не открывать частный канал между вами и процессом.

Создать как coproc.sh:

#!/bin/bash 

IFS= 

run_in_coproc() { 
    echo "coproc[$1] -> main" 
    read -r; echo $REPLY 
} 

# dynamic-coprocess-generator. nice. 
_coproc() { 
    local i o e n=${1//[^A-Za-z0-9_]}; shift 
    exec {i}<> <(:) {o}<> >(:) {e}<> >(:) 
. /dev/stdin <<COPROC "${@}" 
    (("\[email protected]")&) <&$i >&$o 2>&$e 
    $n=($o $i $e) 
COPROC 
} 

# pi-rads-of-awesome? 
for x in {0..5}; do 
    _coproc COPROC$x run_in_coproc $x 
    declare -p COPROC$x 
done 

for x in COPROC{0..5}; do 
. /dev/stdin <<RUN 
    read -r -u \${$x[0]}; echo \$REPLY 
    echo "$x <- main" >&\${$x[1]} 
    read -r -u \${$x[0]}; echo \$REPLY 
RUN 
done 

, а затем

# ./coproc.sh 
declare -a COPROC0='([0]="21" [1]="16" [2]="23")' 
declare -a COPROC1='([0]="24" [1]="19" [2]="26")' 
declare -a COPROC2='([0]="27" [1]="22" [2]="29")' 
declare -a COPROC3='([0]="30" [1]="25" [2]="32")' 
declare -a COPROC4='([0]="33" [1]="28" [2]="35")' 
declare -a COPROC5='([0]="36" [1]="31" [2]="38")' 
coproc[0] -> main 
COPROC0 <- main 
coproc[1] -> main 
COPROC1 <- main 
coproc[2] -> main 
COPROC2 <- main 
coproc[3] -> main 
COPROC3 <- main 
coproc[4] -> main 
COPROC4 <- main 
coproc[5] -> main 
COPROC5 <- main 

и там вы идете, нерест бы то ни было. < (:) открывает анонимную трубу через замену процесса, которая умирает, но труба прилипает, потому что у вас есть ручка к ней. Я обычно делать sleep 1 вместо :, потому что его немного пикантный, и я получаю «файл занят» ошибка - никогда не произойдет, если реальная команда побежала (например, command true)

«Heredoc источников»:

. /dev/stdin <<EOF 
[...] 
EOF 

Это работает на каждой оболочке, которую я когда-либо пробовал, включая busybox/etc (initramfs). Я никогда не видел, чтобы это делалось раньше, я самостоятельно обнаружил это, когда подталкивал, кто знал, что источник может принять аргументы? Но он часто выступает в качестве более управляемой формы eval, если есть такая вещь.

2

я бы также пойти на программу экрана (я знаю, что some1 еще ответ был экран, но это завершение)

не только тот факт, что &, Ctrl + Z BG откреститься, поЬир и т.д.может дать вам неприятный сюрприз, что когда вы покинете работу, вы все равно будете убиты (я не знаю почему, но это случилось со мной, и это не беспокоило меня, потому что я переключился на использование экрана, но я предполагаю, что решение антонизирующего устройства как двойное разветвление бы решить, что), а также экран имеет большое преимущества перед только спиной заземления:

screen will background your process without losing interactive control to it 

и кстати, это вопрос, я никогда бы не спросить в первой очереди :) ... я использовать экран с самого начала делать что-либо в любом unix ... i (почти) НИКОГДА не работайте в оболочке unix/linux, не запуская сначала экран ... и я должен остановиться сейчас, или я начну бесконечную презентацию того, какой хороший экран и что можно сделать для ya ... посмотрите сами, это того стоит;)

2

Существует также команда daemon пакета libslack с открытым исходным кодом.

daemon вполне конфигурируется и заботится обо всех утомительных материалах демона, таких как автоматический перезапуск, ведение журнала или обработка pidfile.

2

Append эту строку на вашу команду:> & - 2> & - < & - &. > & - означает закрытие stdout. 2> & - означает закрытие stderr. < & - означает закрыть stdin. & означает запустить в фоновом режиме. Это работает, чтобы программно начать работу через SSH, тоже:

$ ssh myhost 'sleep 30 >&- 2>&- <&- &' 
# ssh returns right away, and your sleep job is running remotely 
$ 
4

nohup очень хорошо, если вы хотите, чтобы войти ваши данные в файл. Но когда он подходит к фону, вы не можете дать ему пароль, если ваши скрипты просят. Я думаю, вы должны попробовать screen. его утилиту, которую вы можете установить на свой дистрибутив linux, используя yum, например, на CentOS yum install screen, затем получите доступ к вашему серверу через шпатлевку или другое программное обеспечение в вашем типе оболочки screen. Он откроет экран [0] в замазке. Делай свою работу. Вы можете создать больше экрана [1], экран [2] и т. Д. В том же сеансе шпатлевки.

Основные команды, которые вы должны знать:

Чтобы запустить экран

экран


Для с reate следующий экран

Ctrl + а + с


Для перехода к п доб экран, созданный

Ctrl + A + п


Для д etach

Ctrl + A + D


Во время работы закройте шпатлевку.И в следующий раз, когда вы входите с помощью типа замазки

экрана -r

Для повторного подключения к экрану, и вы можете увидеть ваш процесс все еще работает на экране. И для выхода из экрана типа #exit.

Для получения дополнительной информации см. man screen.

4

В системе Debian на базе (на удаленной машине) Установка:

Sudo APT-получить установку tmux

Использование:

tmux

вы хотите

Чтобы переименовать сеанс:

Ctrl + B затем $

комплект Имя

Для выхода из сеанса:

Ctrl + B затем D

(это оставляет tmux сессии). Затем вы можете выйти из SSH.

Когда вам нужно вернуться/проверить на ней снова, запустить SSH и введите

tmux присоединять session_name

Это вернет вас к вашей tmux сессии.

2

Для большинства процессов можно псевдо-демоном, используя этот старый Linux командной строки трюк:

# ((mycommand &)&) 

Например:

# ((sleep 30 &)&) 
# exit 

Затем запустите новое окно терминала и:

# ps aux | grep sleep 

Показать, что sleep 30 все еще работает.

Что вы сделали, это начальный процесс как дочерний элемент ребенка, и когда вы выходите, команда nohup, которая обычно запускает процесс для выхода, не каскадирует до grand-child, оставляя ее как сиротский процесс, все еще работает.

Я предпочитаю, чтобы этот подход «поставил его и забыл», не нужно иметь дело с nohup, screen, tmux, перенаправлением ввода-вывода или любым из этих материалов.

1

Принято с ответом: nohup. Я предпочел бы использовать pm2. Использование pm2 over nohup имеет множество преимуществ, таких как сохранение приложения в рабочем состоянии, ведение журнальных файлов для приложений и множество других функций. Для более подробной информации check this out.

Для установки pm2 необходимо скачать npm. Для системы на основе Debian

sudo apt-get install npm 

и Redhat

sudo yum install npm 

Или вы можете последовать these instruction. После установки НПМ использовать его для установки PM2

npm install [email protected] -g 

После того, как его сделали вы можете запустить приложение на

$ pm2 start app.js    # Start, Daemonize and auto-restart application (Node) 
$ pm2 start app.py    # Start, Daemonize and auto-restart application (Python) 

Для использования процесса мониторинга следующих команд:

$ pm2 list      # List all processes started with PM2 
$ pm2 monit      # Display memory and cpu usage of each app 
$ pm2 show [app-name]   # Show all informations about application 

Управление процессами с использованием имени приложения или идентификатора процесса или управления всеми процессами SES вместе:

$ pm2 stop  <app_name|id|'all'|json_conf> 
$ pm2 restart <app_name|id|'all'|json_conf> 
$ pm2 delete <app_name|id|'all'|json_conf> 

Лог-файлы могут быть найдены в

$HOME/.pm2/logs #contain all applications logs 

Бинарные исполняемые файлы могут быть запущены с помощью PM2. Вы должны внести изменения в файл jason. Измените "exec_interpreter" : "node", на "exec_interpreter" : "none". (см. attributes section).

#include <stdio.h> 
#include <unistd.h> //No standard C library 
int main(void) 
{ 
    printf("Hello World\n"); 
    sleep (100); 
    printf("Hello World\n"); 

    return 0; 
} 

Компиляция выше код

gcc -o hello hello.c 

и запустить его с NP2 в фоновом режиме

pm2 start ./hello 
0

На Systemd/Linux, systemd-run хороший инструмент для запуска сеанса независимых процессов. Ненавистники будут ненавидеть