Linux守护进程脚本基于Python3

Linux守护进程脚本基于Python3

一、升级python

该脚本是基于python3编写的
所以需要先升级python

查看 Python 版本号
当 Linux 上安装 Python 后(默认安装),只需要输入简单的命令,就可以查看 Python 的版本号:

python -V
Python 2.7.5

或者是:

python --version
Python 2.7.5

可以看出,系统自带的 Python 版本是 2.7.5。

下载新版本
进入 Python下载页面,选择需要的版本。

这里,我选择的版本是 3.7.2 。

wget https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tgz

解压缩
下载完成之后,进行解压缩:

tar -zxvf Python-3.7.2.tgz

安装配置
进入解压缩后的目录,安装配置:

cd Python-3.7.2/
./configure 

执行 ./configure 时,如果报错:

configure: error: no acceptable C compiler found in $PATH

说明没有安装合适的编译器。这时,需要安装/升级 gcc 及其它依赖包。

yum install make gcc gcc-c++ 

完成之后,重新执行:

./configure 

编译 & 安装
配置完成之后,就可以编译了:

 make 

漫长的等待……完成后,安装:

 make install 

验证
安装成功以后,就可以查看 Python 的版本了:

python -V
Python 2.7.5
python3 -V
Python 3.7.2

一个是旧版本 2.x,另外一个是新版本 3.x。

注意:在 /usr/local/bin/ 下有一个 python3 的链接,指向 bin 目录下的 python 3.7。

设置 3.x 为默认版本
查看 Python 的路径,在 /usr/bin 下面。可以看到 python 链接的是 python 2.7,所以,执行 python 就相当于执行 python 2.7。

ls -al /usr/bin | grep python
-rwxr-xr-x.  1 root root      11216 12月  1 2015 abrt-action-analyze-python
lrwxrwxrwx.  1 root root          7 8月  30 12:11 python -> python2
lrwxrwxrwx.  1 root root          9 8月  30 12:11 python2 -> python2.7
-rwxr-xr-x.  1 root root       7136 11月 20 2015 python2.7

将原来 python 的软链接重命名:

mv /usr/bin/python /usr/bin/python.bak

将 python 链接至 python3:

ln -s /usr/local/bin/python3 /usr/bin/python

这时,再查看 Python 的版本:

python -V
Python 3.7.2

输出的是 3.x,说明已经使用的是 python3了。

配置 yum
升级 Python 之后,由于将默认的 python 指向了 python3,yum 不能正常使用,需要编辑 yum 的配置文件:

vi /usr/bin/yum

同时修改:

vi /usr/libexec/urlgrabber-ext-down

将 #!/usr/bin/python 改为 #!/usr/bin/python2.7,保存退出即可。

二、守护进程脚本

编写守护进程的基类,用于继承
daemon.py

#!/usr/bin/env python
#encoding:utf-8

import os
import sys
import time
import atexit
import signal
 
class Daemon:
  def __init__(self, pidfile='/tmp/daemon.pid', stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
    self.stdin = stdin
    self.stdout = stdout
    self.stderr = stderr
    self.pidfile = pidfile
 
  def daemonize(self):
    if os.path.exists(self.pidfile):
      raise RuntimeError('Already running.')
 
    # First fork (detaches from parent)
    try:
      if os.fork() > 0:
        raise SystemExit(0)
    except OSError as e:
      raise RuntimeError('fork #1 faild: {0} ({1})\n'.format(e.errno, e.strerror))
 
    os.chdir('/')
    os.setsid()
    os.umask(0o22)
 
    # Second fork (relinquish session leadership)
    try:
      if os.fork() > 0:
        raise SystemExit(0)
    except OSError as e:
      raise RuntimeError('fork #2 faild: {0} ({1})\n'.format(e.errno, e.strerror))
 
    # Flush I/O buffers
    sys.stdout.flush()
    sys.stderr.flush()
 
    # Replace file descriptors for stdin, stdout, and stderr
    with open(self.stdin, 'rb', 0) as f:
      os.dup2(f.fileno(), sys.stdin.fileno())
    with open(self.stdout, 'ab', 0) as f:
      os.dup2(f.fileno(), sys.stdout.fileno())
    with open(self.stderr, 'ab', 0) as f:
      os.dup2(f.fileno(), sys.stderr.fileno())
 
    # Write the PID file
    with open(self.pidfile, 'w') as f:
      print(os.getpid(), file=f)
 
    # Arrange to have the PID file removed on exit/signal
    atexit.register(lambda: os.remove(self.pidfile))
 
    signal.signal(signal.SIGTERM, self.__sigterm_handler)
 
  # Signal handler for termination (required)
  @staticmethod
  def __sigterm_handler(signo, frame):
    raise SystemExit(1)
 
  def start(self):
    try:
      self.daemonize()
    except RuntimeError as e:
      print(e, file=sys.stderr)
      raise SystemExit(1)
 
    self.run()
 
  def stop(self):
    try:
      if os.path.exists(self.pidfile):
        with open(self.pidfile) as f:
          os.kill(int(f.read()), signal.SIGTERM)
      else:
        print('Not running.', file=sys.stderr)
        raise SystemExit(1)
    except OSError as e:
      if 'No such process' in str(e) and os.path.exists(self.pidfile): 
        os.remove(self.pidfile)
 
  def restart(self):
    self.stop()
    self.start()
 
  def run(self):
    pass

example_daemon.py

#!/usr/bin/env python
#encoding:utf-8

import os
import sys
import time
 
from daemon import Daemon
 
class TomcatDaemon(Daemon):
  def run(self):
    sys.stdout.write('Daemon started with pid {}\n'.format(os.getpid()))
    while True:

      tomcat = os.popen('ps -fe | grep "/root/tomcat/bin/" | grep -v "grep" | wc -l').read().strip()
      #筛选出进程中含有tomcat且不含有grep,计算出现行数。修改上面的进程监控语句以适应其他应用需求
      if (tomcat == '0'):
        os.system('cd /root/tomcat/bin/;  ./startup.sh')

      sys.stdout.write('Daemon Alive! {}\n'.format(time.ctime()))
      sys.stdout.flush()
 
      time.sleep(5)
 
if __name__ == '__main__':
  PIDFILE = '/tmp/daemon-example.pid'
  LOG = '/tmp/daemon-example.log'
  daemon = TomcatDaemon(pidfile=PIDFILE, stdout=LOG, stderr=LOG)
 
  if len(sys.argv) != 2:
    print('Usage: {} [start|stop]'.format(sys.argv[0]), file=sys.stderr)
    raise SystemExit(1)
 
  if 'start' == sys.argv[1]:
    daemon.start()
  elif 'stop' == sys.argv[1]:
    daemon.stop()
  elif 'restart' == sys.argv[1]:
    daemon.restart()
  else:
    print('Unknown command {!r}'.format(sys.argv[1]), file=sys.stderr)
    raise SystemExit(1)

使用测试:

[daemon] python daemon.py start                     23:45:42
[daemon] cat /tmp/daemon-example.pid                 23:45:49
8532
[daemon] ps -ef|grep 8532 | grep -v grep               23:46:07
 502 8532   1  0 11:45下午 ??     0:00.00 python test.py start
[daemon] tail -f /tmp/daemon-example.log               23:46:20
Daemon started with pid 8532
Daemon Alive! Fri Dec 2 23:45:49 2018
Daemon Alive! Fri Dec 2 23:45:54 2018
Daemon Alive! Fri Dec 2 23:45:59 2018
Daemon Alive! Fri Dec 2 23:46:04 2018
Daemon Alive! Fri Dec 2 23:46:09 2018
Daemon Alive! Fri Dec 2 23:46:14 2018
Daemon Alive! Fri Dec 2 23:46:19 2018
Daemon Alive! Fri Dec 2 23:46:24 2018
Daemon Alive! Fri Dec 2 23:46:29 2018
Daemon Alive! Fri Dec 2 23:46:34 2018
 
[daemon] python test.py stop                     23:46:36
[daemon] ps -ef|grep 8532 | grep -v grep               23:46:43

你可能感兴趣的:(运维,服务器,守护进程)