В Linux, как предотвратить остановку фонового процесса после закрытия SSH-клиента

StackOverflow https://stackoverflow.com/questions/285015

Вопрос

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

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

Это было полезно?

Решение

Ознакомьтесь с & предложением nohup &; Программа.

Другие советы

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

Когда сеанс закрыт, процесс получает сигнал SIGHUP, который он явно не перехватывает. Чтобы предотвратить это, вы можете использовать команду nohup при запуске процесса или встроенную команду bash 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.

демонизировать?нохап?ЭКРАН?(tmux ftw, экран - это мусор ;-)

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

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

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

Создавать как 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 "${@}"
    (("\$@")&) <&$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).Я никогда не видел, чтобы это делалось раньше, я самостоятельно обнаружил это во время подталкивания, кто знал, что исходный код может принимать аргументы?Но это часто служит гораздо более управляемой формой оценки, если такая вещь существует.

nohup blah &

Замените имя вашего процесса на бла!

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

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

Это помещает его в фон, а затем отправляет результаты вам по почте. Это часть cron.

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

Вы можете найти информацию о демонизирующих процессах в таких книгах, как «& Стивенса; Advanced Network Program», том 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, точка com), если вам нужен источник для daemonize.

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

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

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

В системе на базе Debian (на удаленном компьютере) Установите:

sudo apt-получить установку tmux

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

tmux

выполняйте нужные команды

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

Ctrl+B тогда $

установленное Имя

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

Ctrl+B тогда D

(это завершает сеанс tmux).Затем вы можете выйти из системы по SSH.

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

tmux присоединить имя_сессии_сообщения

Это вернет вас к вашему сеансу tmux.

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

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

Для запуска экрана

Экран

<Ч>

Чтобы c открыть следующий экран

Ctrl + A + C

<Ч>

Чтобы перейти на n дополнительный экран, который вы создали

Ctrl + а + п

<Ч>

До d этажа

Ctrl + A + D

<Ч>

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

screen -r

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

Подробнее см. <=>.

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

# ((mycommand &)&)

Например:

# ((sleep 30 &)&)
# exit

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

# ps aux | grep sleep

покажет, что sleep 30 все еще работает.

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

Я предпочитаю это & установить и забыть " подход, нет необходимости иметь дело с screen, <=>, tmux, перенаправлением ввода-вывода или чем-то подобным.

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

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

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

Используйте экран. Он очень прост в использовании и работает как vnc для терминалов. http://www.bangmoney.org/presentations/screen.html

Если вы также хотите запускать приложения X - используйте xpra вместе с & экраном <экран> < !> Quot;.

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

не только тот факт, что & amp ;, ctrl + z bg disown, nohup и т. д. может преподнести вам неприятный сюрприз, что когда вы выйдете из системы, работа все равно будет убита (я не знаю почему, но это случилось со мной , и это не беспокоило, потому что я переключился на использование экрана, но я думаю, что решение anthonyrisinger, поскольку двойное разветвление решило бы это), также экран имеет major преимущество по сравнению с простым отступлением:

screen will background your process without losing interactive control to it

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

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

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

Добавьте эту строку к вашей команде: > & amp; - 2 > & amp; - < & amp; - & amp ;. > & amp; - означает закрытый стандартный вывод. 2 & Gt; & Amp; - означает закрытие stderr. < & amp; - означает закрытие стандартного ввода. & Усилитель; значит беги в фоновом режиме. Это также работает для программного запуска задания через ssh:

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

Я использовал экранную команду. Эта ссылка подробно описывает, как это сделать

https://www.rackaid.com / блог / Linux-экран-учебник-и-как-к / # начиная

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

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

sudo apt-get install npm

и для Redhat

sudo yum install npm

Или вы можете следовать этой инструкции . После установки npm используйте его для установки pm2

npm install pm2@latest -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

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

$ 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. Вы должны внести изменения в файл Джейсона. Измените "exec_interpreter" : "node" на "exec_interpreter" : "none". (см. раздел атрибутов ).

#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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top