Фоновый Python: Полное руководство по запуску скриптов в Linux без привязки к терминалу

Фоновый Python: Полное руководство по запуску скриптов в Linux без привязки к терминалу

Запуск Python-скриптов в фоновом режиме — фундаментальный навык для любого разработчика, работающего с Linux. Это позволяет выполнять долгие задачи, веб-серверы, ботов или обработчики данных, не блокируя терминал и продолжая работу в системе. В этой статье мы разберем все методы — от простейших до профессиональных, с подробными примерами и объяснением, что происходит «под капотом».

Почему просто закрыть терминал недостаточно?

Если запустить скрипт командой python3 script.py и закрыть терминал, процесс будет завершен вместе с родительской сессией. Это происходит потому, что процесс привязан к управляющему терминалу (controlling terminal). Нам нужно либо отвязать процесс от терминала, либо сделать его независимым.

Важно: Фоновый режим ≠ параллельное выполнение (многопоточность/многопроцессность). Речь идет о запуске процесса, который продолжает жить после закрытия сессии пользователя.

Базовые методы: &, nohup и disown

1. Амперсанд (&) — простейший фон

Добавьте символ & в конец команды:

python3 long_script.py &

Скрипт запустится в фоне, но останется привязан к текущему терминалу. Если терминал закрыть — процесс, скорее всего, получит сигнал SIGHUP и завершится.

2. nohup — игнорирование сигнала HUP

Команда nohup (no hang up) заставляет процесс игнорировать сигнал SIGHUP, отправляемый при закрытии терминала:

nohup python3 script.py &

Вывод скрипта по умолчанию перенаправляется в файл nohup.out. Вы можете перенаправить его самостоятельно:

nohup python3 script.py > output.log 2>&1 &

Совет: Всегда перенаправляйте stdout и stderr в файлы при использовании nohup, иначе вы потеряете логи и сообщения об ошибках.

3. disown — «открепить» уже запущенный процесс

Если вы уже запустили скрипт в фоне с помощью &, но забыли про nohup, можно «открепить» его от сессии:

  1. Запустите скрипт: python3 script.py &
  2. Выполните jobs -l чтобы увидеть ID задания (например, [1] 12345).
  3. Выполните disown %1 (где 1 — номер задания) или disown -h 12345 (где 12345 — PID).

Теперь процесс переживет закрытие терминала.

Профессиональные подходы: systemd и screen/tmux

systemd — управление как системной службой

Идеально для скриптов, которые должны работать постоянно и автоматически перезапускаться. Создайте файл службы:

sudo nano /etc/systemd/system/my_script.service

Содержимое файла:

[Unit]
Description=My Python Script
After=network.target

[Service]
Type=simple
User=username
WorkingDirectory=/path/to/script
ExecStart=/usr/bin/python3 /path/to/script/script.py
Restart=on-failure

[Install]
WantedBy=multi-user.target

Далее:

  • sudo systemctl daemon-reload
  • sudo systemctl start my_script
  • sudo systemctl enable my_script (для автозапуска при загрузке)
  • sudo systemctl status my_script (проверка состояния)

tmux/screen — виртуальные терминалы

Эти программы создают сессии, которые можно «отключать» и подключать заново.

# Установка tmux: sudo apt install tmux
# Создание сессии:
tmux new -s mysession
# Запуск скрипта внутри сессии:
python3 script.py
# Отсоединение: Ctrl+B, затем D
# Повторное подключение: tmux attach -t mysession

Сессия tmux продолжит работать в фоне даже после закрытия SSH-соединения.

Практические рекомендации

  • Логирование: Всегда настраивайте ротацию логов (logrotate) для долгоживущих процессов.
  • Мониторинг: Используйте htop, ps aux | grep python или systemctl status для отслеживания.
  • Виртуальные окружения: При использовании systemd укажите полный путь к python в venv в ExecStart.
  • Остановка процессов: Найдите PID через ps aux | grep script.py и отправьте сигнал kill PID или kill -9 PID (принудительно).

FAQ — Часто задаваемые вопросы

Как проверить, работает ли мой фоновый Python-скрипт?

Используйте команду ps aux | grep python или pgrep -f "script.py". Для systemd служб — systemctl status имя_службы.

Как остановить фоновый скрипт?

Найдите его PID (идентификатор процесса) через ps aux | grep python и выполните kill PID. Для systemd: sudo systemctl stop имя_службы.

Куда сохраняются логи при использовании nohup?

По умолчанию — в файл nohup.out в текущей директории. Рекомендуется явно перенаправлять вывод: nohup python3 script.py > mylog.log 2>&1 &.

Чем systemd лучше nohup?

Systemd обеспечивает автоматический перезапуск при сбоях, централизованное управление, ротацию логов, запуск от определенного пользователя и интеграцию в систему инициализации.

Можно ли запустить несколько копий скрипта в фоне?

Да, но они должны использовать разные PID. Убедитесь, что скрипты не конфликтуют за ресурсы (порты, файлы). Для systemd можно создать шаблон службы (@).

Как сделать, чтобы скрипт запускался при загрузке системы?

Лучший способ — создать службу systemd и выполнить sudo systemctl enable имя_службы. Альтернатива — добавить команду с nohup в /etc/rc.local (устаревший метод).