首页 > 解决方案 > 当父 python 脚本被 systemd 停止时子进程退出

问题描述

我是 python 新手,想熟悉一下,所以我创建了一个 python 脚本,它使用子进程中的 Popen 来执行 bash 脚本。bash 脚本设置环境并执行 c++ 程序以在后台运行。

预期用途是将 python 脚本作为监视 C++ 进程的服务运行,如果 C++ 进程退出,则再次运行 bash 启动脚本。

如果我从命令行 ( ./proc_watchdog.py) 启动 python 脚本,然后按 ctr+c,一切都会按预期运行,C++ 进程将继续运行。

如果我然后使用 systemd 执行 python 脚本,systemd start pythonscript.service然后停止它systemd stop pythonscript.service,C++ 程序就会退出。

.service 文件:

[Unit]
Description=RustDedicated watchdog service
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=always
RestartSec=1
User=scriptuser
ExecStart=/path/to/C++_Prog_Dir/proc_watchdog.py

[Install]
WantedBy=multi-user.target

蟒蛇脚本:

#!/usr/bin/python3

import subprocess as sp
import os
import psutil
import time

backgroundProc = "Procname"

def processWatchdog():
   waitCount = 0;

   while True:
      procList = []

      for proc in psutil.process_iter():
         procList.append(proc.as_dict(attrs=['name']))

      found = 0
      for pname in procList:
         if backgroundProc == pname['name']:
            print("Process running")
            found = 1

      if found == 0:
         print("Process not found...")
         waitCount += 1
         if waitCount == 3:
            p = sp.Popen(["/path/to/C++_Prog_Dir/start.sh"])
            print("Restarting")
            p.wait()
            waitCount = 0
            print("Restarted")

      time.sleep(2)

if __name__ == '__main__':
   processWatchdog()

Bash 脚本示例:

#!/bin/bash

./c++_process &>> /dev/null &

exit 0

谁能帮我理解为什么 python 脚本在每种执行方式下的行为都会不同?

标签: subprocesssystemdpython-3.7

解决方案


做适当的监督让父母等待孩子。当孩子退出时,重新启动它。这就是 DJB 的 daemontools 所做的。

更改您的脚本:

./c++_process &>> /dev/null &

至:

exec ./c++_process &>> /dev/null

然后,您的看门狗将在p.wait()返回时立即收到警报,因为它必须重新启动程序,因为它已经退出。这样,您的看门狗就可以简化为:

import subprocess as sp
import time

def processWatchdog():

   while True:
       p = sp.Popen(["/path/to/C++_Prog_Dir/start.sh"])
       p.wait()

       time.sleep(2)

if __name__ == '__main__':
   processWatchdog()

这只是以 2 秒的延迟重新启动程序。


推荐阅读