systemctl系统服务
环境:centos7
实现
正常情况下我们在/usr/lib/systemd/system/目录下,创建一个以.service 后缀的文件,如cdr.service
[Unit] Description=cdr After=network.target [Service] ExecStart=/opt/pbx/cdr/cdr.py Type=forking [Install] WantedBy=multi-user.target
使用方式:
# 启动 systemctl start cdr # 关闭 systemctl stop cdr #查看状态 systemctl status cdr #开启自启动 systemctl enable cdr #关闭开启自启动 systemctl enable cdr
正常的python程序都可以这么用,但是下面这种情况下,还使用上面的.servcie文件创建方式就不好使了,如下
#!/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()
这次最大的区别就是在python程序中fork了一个子进程,这种情况下第一种方式就不好使了,经过多次测试发现下面这种方式可以实现我们的效果
[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