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

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

Ответ 3

Когда сеанс закрыт, процесс получает сигнал 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.

Ответ 4

демон? поЬир? SCREEN? (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 "${@}"
    (("\[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 sourcing":

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

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

Ответ 5

nohup blah &

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

Ответ 6

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

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

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

Ответ 7

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

Вы можете найти информацию о процессах демонализации в таких книгах, как "Расширенная сетевая программа, Vol 1, 3 Edn" или Rochkind "Стивенс Стивенс".

Недавно (за последние пару лет) пришлось иметь дело с непоколебимой программой, которая не демонанизировала себя должным образом. Я в конечном итоге столкнулся с этим, создав общую программу демонатизации - похожую на 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 Overflow Questions) в качестве файла daemonize-1.10.tgz в packages подкаталог.

Ответ 8

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

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

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

Ответ 9

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

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

Ответ 10

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

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

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

Экран


В c введите следующий экран

Ctrl + A + C


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

Ctrl + а + п


d etach

Ctrl + A + D


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

screen -r

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

Подробнее см. man screen.

Ответ 11

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

sudo apt-get install tmux

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

tmux

выполнить команды, которые вы хотите

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

Ctrl + B, затем $

установить имя

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

Ctrl + B, затем D

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

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

tmux attach session_name

Он вернет вас в ваш сеанс tmux.

Ответ 12

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

# ((mycommand &)&)

Например:

# ((sleep 30 &)&)
# exit

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

# ps aux | grep sleep

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

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

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

Ответ 14

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

Ответ 15

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

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

screen will background your process without losing interactive control to it

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

Ответ 16

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

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

Ответ 17

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

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

Ответ 19

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

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

sudo apt-get install npm

и для Redhat

sudo yum install npm

Или вы можете следовать этой инструкции. После установки npm используйте его для установки 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

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

$ 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". (см. Раздел атрибуты).

#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

Ответ 20

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