В Linux, как предотвратить остановку фонового процесса после закрытия SSH-клиента
-
08-07-2019 - |
Вопрос
Я работаю на компьютере с 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 является хороший инструмент для запуска независимых от сессии процессов. Ненавистники будут ненавидеть