Ответ 1
Проверьте программу nohup.
Я работаю над Linux-машиной через SSH (Putty). Мне нужно оставить процесс, работающий в течение ночи, поэтому я подумал, что могу сделать это, запустив процесс в фоновом режиме (с амперсандом в конце команды) и перенаправляя stdout в файл. К моему удивлению, это не работает. Как только я закрою окно 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.
демон? поЬир? 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, если есть такая вещь.
nohup blah &
Замените имя своего процесса на blah!
Лично мне нравится команда "пакет".
$ batch
> mycommand -x arg1 -y arg2 -z arg3
> ^D
Это заносит его на задний план, а затем отправляет вам результаты. Это часть cron.
Как отмечали другие, для запуска процесса в фоновом режиме, чтобы вы могли отключиться от сеанса 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
подкаталог.
Nohup позволяет клиенту не убивать, если родительский процесс убит, для аргумента при выходе из системы. Еще лучше использовать:
nohup /bin/sh -c "echo \$\$ > $pidfile; exec $FOO_BIN $FOO_CONFIG " > /dev/null
Nohup делает процесс, в котором вы начинаете защищаться от завершения, который ваш SSH-сеанс и его дочерние процессы убивают при выходе из системы. Команда, которую я дал, предоставляет вам способ хранения pid приложения в файле pid, чтобы вы могли впоследствии его убить позже и разрешить запуск процесса после того, как вы вышли из системы.
Если вы используете экран для запуска процесса с правами root, остерегайтесь возможности атак на повышение привилегий. Если ваша собственная учетная запись каким-то образом скомпрометирована, будет прямой способ захватить весь сервер.
Если этот процесс необходимо регулярно запускать, и у вас есть достаточный доступ на сервере, лучшим вариантом будет использование cron для запуска задания. Вы также можете использовать init.d(супер-демон), чтобы начать свой процесс в фоновом режиме, и он может завершить работу, как только это будет сделано.
nohup
очень хорошо, если вы хотите записывать свои данные в файл. Но когда он подходит к фону, вы не можете дать ему пароль, если ваши скрипты просят. Я думаю, вы должны попробовать screen
. его утилиту, которую вы можете установить в своем дистрибутиве linux, используя yum, например, на CentOS yum install screen
, затем получите доступ к вашему серверу с помощью шпатлевки или другого программного обеспечения в вашем типе оболочки screen
. Он откроет экран [0] в замазке. Делай свою работу. Вы можете создать больше экрана [1], экран [2] и т.д. В том же сеансе шпатлевки.
Основные команды, которые вам нужно знать:
Для запуска экрана
В c введите следующий экран
Чтобы перейти к экрану n ext, который вы создали
d etach
Во время работы закройте шпатлевку. И в следующий раз, когда вы входите в систему через тип шпаги
Чтобы снова подключиться к экрану, вы можете видеть, что ваш процесс все еще работает на экране. И для выхода из экрана типа #exit.
Подробнее см. man screen
.
В системе на базе Debian (на удаленном компьютере) Установка:
sudo apt-get install tmux
Использование:
tmux
выполнить команды, которые вы хотите
Чтобы переименовать сеанс:
Ctrl + B, затем $
установить имя
Для выхода из сеанса:
Ctrl + B, затем D
(это оставляет сеанс tmux). Затем вы можете выйти из SSH.
Когда вам нужно снова вернуться/проверить его, запустите SSH и введите
tmux attach session_name
Он вернет вас в ваш сеанс tmux.
Для большинства процессов вы можете псевдодамонизировать, используя этот старый трюк командной строки Linux:
# ((mycommand &)&)
Например:
# ((sleep 30 &)&)
# exit
Затем запустите новое окно терминала и:
# ps aux | grep sleep
Покажет, что sleep 30
все еще работает.
Записанный процесс запускается как дочерний элемент дочернего элемента, и когда вы выходите, команда nohup
, которая обычно запускает процесс для выхода, не каскадирует до grand-child, оставляя его как сиротский процесс, все еще запущенный.
Я предпочитаю этот подход "установить его и забыть", не нужно иметь дело с nohup
, screen
, tmux, перенаправлением ввода/вывода или любым из этих материалов.
Используйте экран. Он очень прост в использовании и работает как vnc для терминалов. http://www.bangmoney.org/presentations/screen.html
Если вы также захотите запустить X-приложения, используйте xpra вместе с "экраном".
я тоже поеду на экранную программу (я знаю, что some1 else ответ был экраном, но это завершение)
не только тот факт, что &, ctrl + z bg disown, nohup и т.д. могут дать вам неприятное удивление, что когда вы покинете работу, вы все равно будете убиты (я не знаю почему, но это случилось со мной, и это не потрудился с этим, потому что я переключился на использование экрана, но я предполагаю, что решение антонизирующего устройства, так как двойное форсирование разрешит это), также экран имеет преимущество major перед простом заземлением:
screen will background your process without losing interactive control to it
и btw, это вопрос, который я бы никогда не спросил в первую очередь:)... я использую экран с самого начала делать что-либо в любом unix... я (почти) НИКОГДА не работаю в оболочке unix/linux без начального экрана сначала... и я должен остановиться сейчас, или я начну бесконечную презентацию того, что хорошего экрана и что может сделать для тебя... посмотри сам, это того стоит;)
Также существует команда daemon пакета libslack с открытым исходным кодом.
daemon
вполне конфигурируется и заботится обо всех утомительных демонах, таких как автоматический перезапуск, ведение журнала или обработка pidfile.
Добавьте эту строку в свою команду: > & - 2 > & - < & - &. > & - означает закрытие stdout. 2 > & - означает закрытие stderr. < & - означает закрытие stdin. и средства запускаются в фоновом режиме. Это работает, чтобы программно запустить работу через ssh тоже:
$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$
Я использовал команду экрана. Эта ссылка содержит подробную информацию о том, как это сделать
https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/#starting
Принятые ответы позволяют использовать 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
В systemd/Linux, systemd-run - хороший инструмент для запуска сессионных процессов. Ненависты будут ненавидеть