通常不要在这里发布信息,但是我正在把头发撕掉。我有一个Python脚本,它在启动时会分叉,并负责启动其他一系列进程。该脚本曾经在启动时通过sysvinit启动,但是最近我升级到Debian Jessie,因此对其进行了修改,使其可以通过systemd启动。
不幸的是,我遇到了一个我无法解决的问题。当您直接在用户外壳程序中启动脚本时,它将正确启动其子进程,并且当脚本退出时,子进程将被孤立并继续运行。
通过systemd启动时,如果父进程退出,则子进程也全部退出(嗯,它们在其中启动的Screen消失并显示为Dead ???)。
理想情况下,我需要能够在不终止所有子进程的情况下重新启动父脚本,我是否缺少某些东西?
谢谢!
[Unit]
Description=Server commander
After=network.target
[Service]
User=serveruser
Type=forking
PIDFile=/var/Server/Server.pid
ExecStart=/var/Server/Server.py
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
编辑:我可能需要指出Python脚本本质上是其子进程的“控制器”。它根据中央服务器的请求在gnu屏幕中启动和停止服务器。它通常一直在运行,不会生成服务并退出。但是在某些情况下,我希望能够在不终止子进程的情况下重新加载脚本,即使这意味着这些进程被孤立为pid1。实际上,即使Python脚本以如下方式启动进程也没有关系:父进程,如果可能的话。
关于其工作原理的更好解释:
- Systemd产生/Server.py
- Server.py分叉并为Systemd写入pid文件
- 然后,Server.py根据其指示在gnu屏幕中生成服务器进程
- Server.py继续运行以执行从服务器请求的任何重新启动
在不使用Systemd的情况下启动时,可以重新启动Server.py,并且启动的gnu屏幕不受影响。使用Systemd启动时,当Server.py关闭时,它们会被杀死,而不是将这些屏幕进程孤立为pid 1。
ExecStop=
不需要。systemd在停止时的默认操作是杀死进程。您可能需要查看KillMode=
指令的文档。
simple
或forking
,实际上),不得已将是Type=oneshot
,RemainAfterExit=yes
和KillMode=control-group
。
Server.py
代码和启动的服务如何分叉(如果它们分叉)的描述,就很难提供解决方案。但是,一般来说,这是准备协议不匹配的问题。