Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Daemon процессы в Unix/Linux
Daemon (демон) - это фундаментальное понятие в Unix/Linux архитектуре. Это специальный тип процесса, который работает в фоне без прямого взаимодействия с пользователем.
Что такое Daemon процесс
Daemon - это процесс, который:
- Работает в фоне (background)
- Не привязан к терминалу (no controlling terminal)
- Не может получать сигналы от клавиатуры
- Обычно запускается при загрузке системы и работает до выключения
- Выполняет какой-либо сервис для системы или других приложений
Характеристики Daemon процессов
1. Отсутствие контролирующего терминала
# Обычный процесс привязан к терминалу
ps aux | grep bash
# TTY не пусто (pts/0, pts/1 и т.д.)
# Daemon процесс не привязан к терминалу
ps aux | grep sshd
# TTY = ?
2. Независимость от сессии
- Daemon отделён от сессии, которая его создала
- Закрытие терминала не убивает daemon
- SIGHUP сигнал на закрытие терминала не влияет
3. Переопределение файловых дескрипторов
- stdin перенаправлен на /dev/null
- stdout и stderr обычно логируются в файл или syslog
Как создать Daemon процесс (классический подход)
#!/bin/bash
# Создание daemon процесса
# 1. Fork: создаём child процесс
# 2. Parent выходит (exit)
# 3. Child становится независимым
# 4. Child создаёт новую сессию (setsid)
# 5. Child переходит в безопасную директорию
# 6. Child переопределяет файловые дескрипторы
# Пример простого скрипта
nohup my_long_running_script.sh > /var/log/my_daemon.log 2>&1 &
Python пример создания daemon'а:
import os
import sys
import atexit
from pathlib import Path
class Daemon:
def __init__(self, pidfile, stdout='/dev/null', stderr='/dev/null'):
self.stdout = stdout
self.stderr = stderr
self.pidfile = pidfile
def daemonize(self):
# First fork
try:
pid = os.fork()
if pid > 0:
sys.exit(0) # Parent выходит
except OSError as err:
sys.stderr.write(f"fork #1 failed: {err}")
sys.exit(1)
# Отсоединяемся от parent environment
os.chdir("/")
os.setsid() # Создаём новую сессию
os.umask(0)
# Second fork для дополнительной безопасности
try:
pid = os.fork()
if pid > 0:
sys.exit(0) # Parent (первый child) выходит
except OSError as err:
sys.stderr.write(f"fork #2 failed: {err}")
sys.exit(1)
# Переопределяем стандартные потоки
sys.stdout.flush()
sys.stderr.flush()
si = open('/dev/null', 'r')
so = open(self.stdout, 'a+')
se = open(self.stderr, 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
# Записываем PID
atexit.register(self.delpid)
pid = str(os.getpid())
Path(self.pidfile).write_text(pid + '\n')
def delpid(self):
os.remove(self.pidfile)
def start(self):
self.daemonize()
self.run()
def run(self):
# Здесь основной код daemon'а
while True:
print("Daemon работает...")
import time
time.sleep(10)
if __name__ == '__main__':
daemon = Daemon('/var/run/my_daemon.pid')
daemon.start()
Systemd сервисы (современный подход)
В современных Linux системах daemon'ы управляются через systemd:
# /etc/systemd/system/my-daemon.service
[Unit]
Description=My Custom Daemon
After=network.target
[Service]
Type=simple
User=daemon_user
WorkingDirectory=/opt/my-daemon
ExecStart=/opt/my-daemon/run.sh
Restart=always
RestartSec=10
# Логирование
StandardOutput=journal
StandardError=journal
SyslogIdentifier=my-daemon
[Install]
WantedBy=multi-user.target
# Управление daemon'ом
sudo systemctl start my-daemon
sudo systemctl stop my-daemon
sudo systemctl restart my-daemon
sudo systemctl enable my-daemon # Автозагрузка при старте
sudo systemctl status my-daemon
sudo journalctl -u my-daemon -f # Логи в реальном времени
Типичные примеры Daemon процессов
# Веб-серверы
ps aux | grep nginx
ps aux | grep apache2
ps aux | grep -E '(python|node).*app.py'
# SSH сервер
ps aux | grep sshd
# DNS сервер
ps aux | grep named
# Database
ps aux | grep mysqld
ps aux | grep postgres
# Cron - планировщик задач
ps aux | grep cron
# Syslog - сбор логов
ps aux | grep rsyslog
# Docker
ps aux | grep dockerd
Практическая работа с Daemon'ами в DevOps
1. Проверка daemon'а
# PID, PPid, TTY, статус
ps -p <pid> -o pid,ppid,tty,stat,cmd
# Все процессы вида daemon
ps aux | grep -E '[d]aemon'
# Сигналы, которые процесс может получить
kill -l
# Отправка сигнала
kill -HUP <pid> # SIGHUP - перезагрузка конфига
kill -TERM <pid> # SIGTERM - graceful shutdown
kill -KILL <pid> # SIGKILL - принудительное убийство
2. Логирование daemon'а
# Logrotate для ротации логов
# /etc/logrotate.d/my-daemon
/var/log/my-daemon.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
postrotate
systemctl reload my-daemon > /dev/null 2>&1 || true
endscript
}
3. Мониторинг daemon'а
# Использование supervisord для мониторинга
# /etc/supervisor/conf.d/my-daemon.conf
[program:my-daemon]
command=/opt/my-daemon/run.sh
autostart=true
autorestart=true
user=daemon_user
log_stdout=true
log_stderr=true
stdout_logfile=/var/log/my-daemon.log
# Управление
supervisorctl start my-daemon
supervisorctl restart my-daemon
supervisorctl status
Различия между типами процессов
Обычный процесс:
- Привязан к терминалу
- Получает SIGHUP на закрытие терминала
- TTY: pts/0, pts/1 и т.д.
Background процесс (jobs):
- nohup ./script.sh &
- Работает в фоне, но зависит от сессии
- TTY: ?
Daemon процесс:
- Полностью независим
- Родитель = init (PID 1)
- PPID = 1 или systemd (PID 1)
- TTY = ?
Выводы
Daemon процессы - это основа инфраструктуры Linux. Понимание того, как они работают, критично для DevOps инженера при:
- Разработке сервисов и микросервисов
- Управлении инфраструктурой через systemd
- Диагностике проблем
- Настройке логирования и мониторинга
- Оптимизации и масштабировании систем
В современном мире systemd упростил работу с daemon'ами, но понимание базовых концепций fork, setsid и файловых дескрипторов остаётся необходимым для полного понимания системы.