Linux run python as demon

How to make a Python script run like a service or daemon in Linux

I wouldn’t recommend you to choose 2., because you would be, in fact, repeating cron functionality. The Linux system paradigm is to let multiple simple tools interact and solve your problems. Unless there are additional reasons why you should make a daemon (in addition to trigger periodically), choose the other approach.

Also, if you use daemonize with a loop and a crash happens, no one will check the mail after that (as pointed out by Ivan Nevostruev in comments to this answer). While if the script is added as a cron job, it will just trigger again.

Here’s a nice class that is taken from here:

#!/usr/bin/env python import sys, os, time, atexit from signal import SIGTERM class Daemon: """ A generic daemon class. Usage: subclass the Daemon class and override the run() method """ def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): self.stdin = stdin self.stdout = stdout self.stderr = stderr self.pidfile = pidfile def daemonize(self): """ do the UNIX double-fork magic, see Stevens' "Advanced Programming in the UNIX Environment" for details (ISBN 0201563177) http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 """ try: pid = os.fork() if pid > 0: # exit first parent sys.exit(0) except OSError, e: sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.exit(1) # decouple from parent environment os.chdir("/") os.setsid() os.umask(0) # do second fork try: pid = os.fork() if pid > 0: # exit from second parent sys.exit(0) except OSError, e: sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.exit(1) # redirect standard file descriptors sys.stdout.flush() sys.stderr.flush() si = file(self.stdin, 'r') so = file(self.stdout, 'a+') se = file(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()) # write pidfile atexit.register(self.delpid) pid = str(os.getpid()) file(self.pidfile,'w+').write("%s\n" % pid) def delpid(self): os.remove(self.pidfile) def start(self): """ Start the daemon """ # Check for a pidfile to see if the daemon already runs try: pf = file(self.pidfile,'r') pid = int(pf.read().strip()) pf.close() except IOError: pid = None if pid: message = "pidfile %s already exist. Daemon already running?\n" sys.stderr.write(message % self.pidfile) sys.exit(1) # Start the daemon self.daemonize() self.run() def stop(self): """ Stop the daemon """ # Get the pid from the pidfile try: pf = file(self.pidfile,'r') pid = int(pf.read().strip()) pf.close() except IOError: pid = None if not pid: message = "pidfile %s does not exist. Daemon not running?\n" sys.stderr.write(message % self.pidfile) return # not an error in a restart # Try killing the daemon process try: while 1: os.kill(pid, SIGTERM) time.sleep(0.1) except OSError, err: err = str(err) if err.find("No such process") > 0: if os.path.exists(self.pidfile): os.remove(self.pidfile) else: print str(err) sys.exit(1) def restart(self): """ Restart the daemon """ self.stop() self.start() def run(self): """ You should override this method when you subclass Daemon. It will be called after the process has been daemonized by start() or restart(). """ 

Источник

Читайте также:  Интерполяция методом ближайшего соседа python

Запуск Python скрипта в виде службы через systemctl/systemd

Есть несколько способов запуска вашей программы в качестве фоновой службы в Linux, таких как crontab, .bashrc и т. д., но сегодня будет разговор о systemd. Изначально я искал способ запустить свой скрипт на Python в качестве фоновой службы, поэтому даже если сервер по какой-то причине перезагрузится, мой скрипт все равно должен работать в фоновом режиме, после небольшого ресерча и я обнаружил, что systemd позволяет мне это сделать. Давайте начнем.

Настройки далее будут производиться на машине с Ubuntu 20.04.

Почти все версии Linux поставляются с systemd из коробки, но если у вас его нет, вы можете просто запустить следующую команду:

sudo apt install -y systemd 

Примечание. Флаг -y означает быструю установку пакетов и зависимостей.

Чтобы проверить, какая версия systemd у вас установлена, просто выполните команду:

Создайте файл python с любым именем. Я назову свой скрипт именем test.py.

import time from datetime import datetime while True: with open("timestamp.txt", "a") as f: f.write("Текущая временная метка: " + str(datetime.now())) f.close() time.sleep(10) 

Приведенный выше скрипт будет записывать текущую метку времени в файл каждые 10 секунд. Теперь напишем сервис.

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

(имя службы, которая тестируется в этом случае)

[Unit] Description=My test service After=multi-user.target [Service] User=deepak Group=admin Type=simple Restart=always ExecStart=/usr/bin/python3 /home//test.py [Install] WantedBy=multi-user.target 

Замените имя пользователя в вашей ОС, где написано . Флаг ExecStart принимает команду, которую вы хотите запустить. Таким образом, в основном первый аргумент — это путь к python (в моем случае это python3), а второй аргумент — это путь к скрипту, который необходимо выполнить. Флаг перезапуска всегда установлен, потому что я хочу перезапустить свою службу, если сервер будет перезапущен.

Читайте также:  Что такое double java

Здесь мы определили User=deepak и Group=admin, чтобы убедиться, что скрипт будет выполняться только от имени пользователя deepak, входящего в группу admin.

Теперь нам нужно перезагрузить демон.

sudo systemctl daemon-reload 

Давайте включим наш сервис, чтобы он не отключался при перезагрузке сервера.

sudo systemctl enable test.service 

А теперь давайте запустим наш сервис.

sudo systemctl start test.service 

Теперь наш сервис работает.

Примечание. Файл будет записан в корневой каталог (/), потому что программа запишет путь с точки зрения systemd. Чтобы изменить это, просто отредактируйте путь к файлу. Например:

import time from datetime import datetime path_to_file = "введите желаемый путь к файлу" while True: with open(path_to_file, "a") as f: f.write("Текущая временная метка: " + str(datetime.now())) f.close() time.sleep(10) 

Есть несколько команд, которые вы можете выполнить для запуска, остановки, перезапуска и проверки состояния.

sudo systemctl stop name_of_your_service 
sudo systemctl restart name_of_your_service 
sudo systemctl status name_of_your_service 

Это было очень поверхностное знакомство с systemd, предназначенное для новичков, которые хотят начать писать свои собственные systemd службы для python.

ПРИМЕЧАНИЕ. Это относится не только к сценариям Python. Вы можете запустить любую программу с ним, независимо от языка программирования, на котором написана ваша программа.

Источник

Как запустить python скрипт на Linux в виде demon

Admin 16.10.2022 Linux, Python

Описание процесса от создания БД и до запуска скрипта.

Соединяемся со своим сервером и дальше работаем через консоль.

Переносим локальный проект на сервер

Создаем директорию для нашего нового приложения:

Клонируем свой git-проект на наш сервер:

Создаем виртуальное окружение python:

Создаем БД в PostgreSQL

Подключаемся к PostgreSQL:

CREATE DATABASE new-application TEMPLATE=template0 ENCODING ‘UTF-8’ LC_COLLATE ‘ru_RU.UTF-8’ LC_CTYPE ‘ru_RU.UTF-8’;

Назначаем привелегии новой таблице:

Читайте также:  Python json dumps cyrillic

Выходим из postgres окружения:

В коде должно быть подключение к PostreSQL

Выдержка из примера подключения к PostreSQL вместе с логированием.

def create_connection (
db_name = ‘new-application’ ,
db_user = ‘ploshadka’ ,
db_password = ‘12345’ ,
db_host = ‘localhost’ ,
db_port = 5432
) :
connection = None
try :
connection = psycopg2. connect (
database = db_name ,
user = db_user ,
password = db_password ,
host = db_host ,
port = db_port ,
)
connection. autocommit = True
except psycopg2. OperationalError as error:
logger. info ( f ‘Ошибка: ‘ )
return connection

Создаем демон для запуска нашего скрипта на python

Внутри этого файла вставляем:

Description=New Application
After=network.target

[Service]
User=ploshadka
Group=www-data
WorkingDirectory=/home/ploshadka/new-application
Environment=»PATH=/home/ploshadka/new-application/venv/bin»
ExecStart=/home/ploshadka/new-application/venv/bin/python bot.py —start
ExecStop=/home/ploshadka/new-application/venv/bin/python bot.py —stop
ExecReload=/home/ploshadka/new-application/venv/bin/python bot.py —restart
TimeoutSec=30
Restart=always

Команды для запуска, остановки, перезагрузки службы

sudo systemctl start new-application
sudo systemctl stop new-application
sudo systemctl start new-application
sudo systemctl reload new-application

Читайте также

У сайта нет цели самоокупаться, поэтому на сайте нет рекламы. Но если вам пригодилась информация, можете лайкнуть страницу, оставить комментарий или отправить мне подарок на чашечку кофе.

Источник

Оцените статью