Фоновое задание (т. Е. Началось с &) все еще имеет свои stdin, stdout и stderr, подключенные к терминалу, в котором оно было запущено. Он может внезапно записать (например, сообщения об ошибках) в терминал («нарушить» задание в передний план) или пауза в ожидании ввода с клавиатуры (сначала нужно поставить его на передний план). Конечно, вы можете перенаправить stdout и stderr в файл или в / dev / null, чтобы фоновая работа не записывалась в терминал.
Фоновое задание также можно поставить на передний план, например. текущее задание переднего плана останавливается, а команда fg
(передний план) используется для помещения заднего плана на передний план. Фоновое задание также может быть достигнуто сигналами от терминала - например. SIGHUP при закрытии терминала, который обычно завершает (большинство) программ, запускаемых в терминале.
С другой стороны, демон, который запускается автоматически init.d, но который также может быть запущен вручную с терминала, с другой стороны, работает независимо от любых терминалов. Даже если он был запущен вручную из терминала, демон будет отключен от терминала, поэтому он не может ни записать (stdout, stderr), ни прочитать (stdin) его. Он также «невосприимчив» к сигналам, посылаемым «автоматически» терминалом. (хотя вы можете отправлять сигналы с помощью kill -signal pid
).
«Фон» и «передний план» относятся к статусу процесса для некоторого терминала - независимо от того, является ли этот процесс в данный момент контролирующим терминалом или нет. Поскольку демоны не подключены к терминалу (но были тщательно отключены от него во всех отношениях), поэтому нельзя сказать, что он работает в фоновом режиме. Демоны - это просто процессы, запущенные без связи с терминалом - ни в фоновом режиме, ни в фоновом режиме.
Если вы используете ps
с опциями, которые показывают, какой терминал использует процесс, вы увидите, что и fore- и backgroundjobs связаны с терминалом (например, tty2). У демонов, с другой стороны, есть "?" в этом поле.
Демоны обычно ведут себя как таковые, даже если они запускаются вручную. Создание вашего собственного демона - это довольно трудоемкий процесс, требующий хитрости, чтобы полностью отключить его от терминала. Вы должны создать свой собственный пользователь / группу для запуска. Обычно вы должны использовать / tmp, / var / tmp или / var / run, если вы хотите, чтобы он создавал файлы - обычно он не должен иметь прав где-либо еще. Поскольку он не может сообщать об ошибках в терминал, вы должны сделать так, чтобы он записывал в файл журнала (например, это собственный файл журнала в / var / log). Демоны должны сделать запись в / var / run со своим текущим PID и должны проверить, не запущен ли еще один экземпляр. Он должен учитывать блокировки (/ var / lock) для файлов или устройств, где это применимо. Он должен отвечать на SIGHUP, перезагружая свои конфигурационные файлы и используя обновленные конфигурации.
Другой момент - как работает большинство демонов. Демон - это обычно один исполняемый файл, который может работать в одном из двух разных режимов; в зависимости от того, был ли это оригинальный демон - родитель - запущен при загрузке или вручную ... или потомком, порожденным этим родителем. Родительский процесс обычно просто сидит и ждет какого-то события - определенного времени, прошедшего времени, попытки подключения к определенному сетевому порту или чего-либо еще. Когда это происходит, родитель создает дочерний процесс, идентичный самому себе (используя системный вызов fork ()), и немедленно возвращается к ожиданию другого события (и, возможно, порождает больше дочерних элементов). Это дочерний процесс, который фактически выполняет эту работу - например, синхронизирует диск, запускает команду (например cron
) или устанавливает сетевое соединение (например, sshd
илиftpd
). Единственное различие между родителем и дочерним элементом заключается в том, что они получили разные идентификаторы PID, а PPID (Parent-PID) дочернего элемента является PID родительского процесса - это можно использовать для определения того, является ли процесс родительским или дочерним. Таким образом, один и тот же процесс должен быть в состоянии работать в двух режимах - в качестве ожидающего (и порождающего) родителя или в качестве работающего потомка.
Хотя написать демон не сложно, он тоже не тривиален - как вы видите, есть немало «хитростей», которые вы должны знать в первую очередь. В целом, я думаю, что написание демона потребует больших усилий для получения очень небольшого выигрыша по сравнению с другими альтернативами:
Использование nohup
или работа disown
в фоновом режиме, как правило, является достаточно хорошей альтернативой, поскольку поддерживает процесс, даже если терминал закрывается. Часто рекомендуется перенаправить stdout и stderr в файл или в / dev / null. Для более интерактивных программ screen
- это хороший способ убрать что-то, пока оно вам не понадобится. at
, batch
а crontab
также стоит подумать.