Задание — запустить на удаленной машине через терминального клиента (такого, как putty) процесс, и не бояться разрыва соединения. Процесс должен продолжать работу на удаленной машине до своего завершения, независимо от того, запущена ли клиентская сессия.
В этой статье не упоминается создание настоящего демона (в его классическом понимании, который запускается при выбранном runlevel, имеет свои команды перезапуска и т.п.), а рассматривается разовый запуск скрипта в фоне для проведения вычислений, профилактических работ и т.п.
Решение №1 : screen
Утилита screen — это виртуальный терминал, запускаемый локально на самой машине. То есть сначала мы подключаемся через сеть к машине, а потом к локально запущенному терминалу, который работает пока нас нет. В этом терминале мы и выполняем команды.
для установки
Debian/Ubuntu: sudo apt-get install screen
Red Hat/Fedora sudo yum install screen
Для запуска нового окна screen достаточно запустить его командой screen, далее запустить нужный процесс. Если нужно отключиться от окна, то нужно нажать ctrl+a, после этого d — процесс продолжится в бекграунде. Если нужно завершить работу screen, нажимаем ctrl+a, и k (screen запросит подтверждение выхода).
После этого можно смело обрывать соединение и заниматься своими делами. Для повторного подключения к screen подключаемся к машине и используем команду screen -r . Если окон было запущено несколько, то можно посмотреть их список командой screen -list , и подключаемся, используя screen -r имя_окна .
Если процесс надо автоматизировать, то запускаем команду с ключами screen -dmS имя_окна процесс . Задаем имя окна и процесс, и screen запустится в свернутом виде с указанным именем окна.
Подробнее можно прочитать в man screen и, например, вот здесь //help.ubuntu.ru/wiki/screen.
Альтернативным решением screen является tmux
Решение №2: nohup / disown
Если вам неинтересно время от времени смотреть на вывод ваших процессов, то можно присмотреться к командам nohup и disown.
Команда nohup блокирует передачу сигнала hangup (клиент отвалился) к процессу. Таким образом, запускаем процесс в бекграунде, говорим ему не следить за коннектом и вуаля — nohupимя_процесса & процесс работает в фоне.
Если процесс уже запущен, но мы хотим перевести его в фон и сделать демоном, то
1. Переводим процесс в спящий режим Ctrl+Z
2. Смотрим, что за работы у нас уже в этом режиме jobs
3. Переводим в background bg [номер_работы_если_он_не_один]
4. Делаем демоном disown -h [%номер_работы]
Есть и другой вариант решения перевода запущенного процесса в демона — подключаемся на эту же машину под другой сессией, находим pid процесса, после чего выполняем kill -20 PID (перевод в спящий режим), и kill -18 PID (продолжить работу в бекграунде).
В любом случае, после любой из этих манипуляций можно закрывать терминалы и не бояться, что процессы отвалятся.
Решение №3 cron / at
Тут даже расписывать нечего — добавляем разовую задачу в кроне или через утилиту at, и она выполняется в фоне в заданное время.
Решение №5 — double fork
Просто, как и все гениальное, для командной оболочки bash (./program.sh &) & . Запускаем процесс, переводим в фон, переводим в фон и убиваем процесс верхнего уровня, после чего процесс наследуется init`ом.
Решение №5 — платформо-зависимые утилиты
Например, для Ubuntu start-stop-daemon , для Red Hat daemon и т.п.
Заключение
Как видим, подходы и способы разные, и какой именно использовать в текущей ситуации, решать вам. Первый способ screen наиболее громоздок и требует установки, но и предлагает больше возможностей. Nohup и double fork позволят запустить программу сходу, не обладая правами суперпользователя. Disown позволит перевести в фон процесс, который уже был запущен и его нежелательно прерывать. Я постарался собрать здесь все известные мне способы решения этой задачи, но если кто-то знает дополнительные способы, пишите в комментарии, я добавлю их в статью.
Спасибо за внимание!