Python development [notes]: add Python program to systemctl system service

Keywords: Python network

systemctl system services

Environment: centos7

  System CTL service usage details

 

Realization

Normally, we create a file with the suffix. Service in the directory / usr/lib/systemd/system /, such as cdr.service

[Unit]
Description=cdr
After=network.target

[Service]
ExecStart=/opt/pbx/cdr/cdr.py
Type=forking

[Install]
WantedBy=multi-user.target

Usage:

# start-up
systemctl start cdr
# Close
systemctl stop cdr
#View state
systemctl status cdr
#Turn on self start
systemctl enable cdr
#Close open self start
systemctl enable cdr

Normal python programs can be used in this way, but in this case, it is not easy to use the above. servcie file creation method, as follows

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import logging
import time
import sys

logging.basicConfig(level=logging.INFO)


def daemon():
    import os
    # create - fork 1
    try:
        pid = os.fork()
        if pid > 0:
            return pid
    except OSError as error:
        logging.error('fork #1 failed: %d (%s)' % (error.errno, error.strerror))
        return -1
    # it separates the son from the father
    os.chdir('/opt/pbx')
    os.setsid()
    os.umask(0)
    # create - fork 2
    try:
        pid = os.fork()
        if pid > 0:
            return pid
    except OSError as error:
        logging.error('fork #2 failed: %d (%s)' % (error.errno, error.strerror))
        return -1
    sys.stdout.flush()
    sys.stderr.flush()
    si = open("/dev/null", 'r')
    so = open("/dev/null", 'a+')
    se = open("/dev/null", 'a+')
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())
    return 0

def main():
    pid = daemon()
    if pid:
        return pid
    while True:
        logging.info('----------')
        time.sleep(1)
main()

The biggest difference this time is to fork a subprocess in the python program. In this case, the first way is not easy to use. After many tests, we found that the following way can achieve our effect

[Unit]
Description=lzl
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/python3 /home/lzl/workspace/cdrservice/main.py

[Install]
WantedBy=multi-user.target

Posted by salomo on Sun, 05 Apr 2020 01:47:01 -0700