Linux: предотвращение остановки фонового процесса после закрытия клиента SSH
Я работаю на машине linux через SSH (Putty). Мне нужно оставить процесс запущенным в течение ночи, поэтому я подумал, что могу сделать это, запустив процесс в фоновом режиме (с амперсандом в конце команды) и перенаправив stdout в файл. К моему удивлению, это не сработает. Как только я закрываю окно шпаклевки, процесс останавливается.
Как я могу предотвратить это??
20 ответов
Я бы рекомендовал использовать экран 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.
демонизации? команды nohup? Экран? (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[] -> 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
и там вы идете, spawn что угодно. sleep 1 вместо :
потому что его немного колоритно, и я бы получил ошибку "файл занят" - никогда не происходит, если выполняется реальная команда (например,command true
)
"heredoc sourcing":
. /dev/stdin <<EOF
[...]
EOF
это работает на каждой оболочке, которую я когда-либо пробовал, включая busybox/etc (initramfs). Я никогда не видел это раньше, я независимо обнаружил его, подталкивая, кто знал, что источник может принять args? Но он часто служит гораздо более управляемой формой eval, если такая вещь существует.
лично мне нравится команда "пакет".
$ batch
> mycommand -x arg1 -y arg2 -z arg3
> ^D
это заполняет его в фоновом режиме, а затем отправляет результаты вам. Это часть крона.
как отмечали другие, чтобы запустить процесс в фоновом режиме, чтобы вы могли отключиться от своего сеанса SSH, вам нужно, чтобы фоновый процесс правильно отключился от своего управляющего терминала - который является псевдо-tty, который использует сеанс SSH.
вы можете найти информацию о процессах демонизации в таких книгах, как "Advanced Network Program, Vol 1, 3rd Edn" Стивенса или "Advanced Unix Programming"Рохкинда.
Я недавно (в последние пару годы) пришлось иметь дело с непокорной программой, которая не демонизировала себя должным образом. Я закончил с этим, создав общую программу демонизации-похожую на 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 и т. д. Поскольку double-dash работает везде, лучше всего использовать его.
вы все еще можете свяжитесь со мной (firstname dot lastname в gmail dot com), Если вы хотите источник для daemonize
.
однако код теперь (наконец) доступен на GitHub в my SOQ (стек
Переполнение вопросов) репозиторий как файл daemonize-1.10.tgz
в
пакетов
подкаталог.
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
Если вы используете экран для запуска процесса как root, остерегайтесь возможности атак на повышение привилегий. Если ваша собственная учетная запись каким-то образом скомпрометирована, будет прямой способ захватить весь сервер.
Если этот процесс должен выполняться регулярно, и у вас есть достаточный доступ на сервере, лучшим вариантом было бы использовать cron для запуска задания. Вы также можете использовать init.d (супер-демон), чтобы начать процесс в фоновом режиме, и он может завершиться, как только он сделанный.
в системе на базе Debian (на удаленной машине) Установить:
sudo apt-get установить tmux
использование:
tmux
выполнить команды, которые вы хотите
переименовать сессии:
Ctrl+B затем $
название
для выхода из сессии:
Ctrl+B затем D
(Это оставляет сеанс tmux). Затем вы можете выйти из SSH.
когда вам нужно вернуться/проверить его снова, запустите SSH и введите
tmux attach session_name
это вернет вас к вашей сессии tmux.
nohup
очень хорошо, если вы хотите записать свои данные в файл. Но когда он переходит в фоновый режим, вы не можете дать ему пароль, если ваши скрипты попросят. Я думаю, вы должны попробовать screen
. его утилита, которую вы можете установить в своем дистрибутиве linux, используя yum, например, на CentOS yum install screen
затем доступ к серверу через шпатлевку или другое программное обеспечение, в вашем типе оболочки screen
. Он откроет экран[0] в putty. Выполнять свою работу. Вы можете создать больше экрана[1], экран[2] и т. д. В том же сеансе шпаклевки.
основные команды, которые вы должны знать:
для запуска экрана
до create следующий экран
ctrl+a+c
перейти к n ext экран, который вы создали
ctrl+a+n
до detach
ctrl+a+d
во время работы закрыть замазкой. И в следующий раз, когда вы входите через putty тип
экран-r
для повторного подключения к экрану, и вы можете увидеть ваш процесс все еще работает на экране. И для выхода из экрана введите #exit.
Подробнее см. В разделе man screen
.
Я бы также пошел на экранную программу (я знаю, что some1 еще ответ был экраном, но это завершение)
не только тот факт, что&, ctrl+z BG disown, nohup и т. д. может дать вам неприятный сюрприз, что, когда вы выходите из системы, работа все равно будет убита (я не знаю, почему, но это случилось со мной, и это не беспокоило меня, потому что я переключился на использование экрана, но я думаю, что решение anthonyrisinger как двойное раздвоение решит это), также экран имеет майор преимущество над просто заземление:
screen will background your process without losing interactive control to it
и кстати, это вопрос, который я бы никогда не задал в первую очередь :) ... я использую экран с самого начала делать что-либо в любом unix ... я (почти) никогда не работаю в оболочке unix/linux без запуска экрана ... и я должен остановиться сейчас, или я начну бесконечную презентацию того, что такое хороший экран и что может сделать для вас ... посмотрите сами, это стоит того ;)
там же демон команда пакета libslack с открытым исходным кодом.
daemon
вполне настраивается и заботится обо всех утомительных вещах демона, таких как автоматический перезапуск, ведение журнала или обработка pidfile.
добавьте эту строку в команду: >&- 2>&- & - означает закрыть stdout. 2 > & - означает закрыть stderr.
$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$
для большинства процессов вы можете псевдо-демонизировать, используя этот старый трюк командной строки Linux:
# ((mycommand &)&)
например:
# ((sleep 30 &)&)
# exit
затем откройте новое окно терминала и:
# ps aux | grep sleep
покажем, что sleep 30
по-прежнему работает.
то, что вы сделали, начинается процесс как ребенок ребенка, и когда вы выходите,nohup
команда, которая обычно запускает процесс выхода, не каскадируется до внука, оставляя его как сиротский процесс, все еще работает.
Я предпочитаю этот подход" установить и забыть", не нужно иметь дело с nohup
, screen
, tmux, перенаправление ввода / вывода или любой из этих вещей.
Если вы также хотите запустить X-приложения-используйте xpra вместе с "экраном".
Я использовал команду экран. Эта ссылка имеет подробную информацию о том, как это сделать
https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/#starting
принятый ответ предлагает использовать nohup. Я бы скорее предложил использовать pm2. Используя pm2 над nohup имеет много преимуществ, как держать применение живым, поддерживает файлы журнала для применения и много больше других особенностей. Более подробно зацените.
установить pm2 вам нужно скачать НПМ. Для Debian на основе система
sudo apt-get install npm
и для Redhat
sudo yum install 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
управление процессами с помощью имени приложения или id процесса или управлять всеми процессами вместе:
$ 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"
, to "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 - хороший инструмент для запуска независимых от сеанса процессов. Ненавистники будут ненавидеть