dmlogv
@dmlogv
Универсальный человек

Как запустить процесс из Python-службы, который продолжит жить после смерти службы?

Я сделал на Python службу, которая может запускать и убивать сторонние процессы (с помощью Popen). Но есть одна маленькая проблема: при выходе из службы (systemctl stop или просто killпроцесса) она уносит с собой в могилу запущенные процессы.

Парочка примеров
  • pyservice.service (Unit-file):
    [Service]
    ExecStart=/opt/pyservice/service.py
  • service.py:
    ...
    subprocess.Popen('server.sh')
    ...
  • server.sh:
    /usr/bin/java -server -jar ./Application.jar &

Что происходит в нашем царстве?
Я запускаю несколько экземпляров server.sh с помощью pyservice.
ps -aef --forest показывает ожидаемое дерево:
python3.6 /opt/pyservice/service.py
\_ [server.sh] <defunct>
/usr/bin/java -server -jar ./Application.jar 
/usr/bin/java -server -jar ./Application.jar

Если я уложу service.py, Application.jar тоже завершится.

Чего мы хотим?
Чтобы после kill service.py или перезапуска pyservice наши запущенные через него server.sh и его содержимое продолжили шуршать.

Что я уже пытался делать?
Разные комбинации os.system, subprocess.Popen, nohup, & и их аргументов.

Что я делаю не так?
  • Вопрос задан
  • 863 просмотра
Пригласить эксперта
Ответы на вопрос 2
NeiroNx
@NeiroNx
Программист
проще всего использовать команду системы screen
os.system("screen /usr/bin/java -server -jar ./Application.jar")

когда сам скрин померает - запущенный процесс продолжает работать
Ответ написан
Попробуйте двойной форк:
  1. create a child via os.fork()
  2. in this child call Popen() which launches the long running process
  3. exit child: Popen process is inherited by init and runs in the background

https://stackoverflow.com/a/41433401

Пример. Пинг продолжит работать после завершения родителя:
import os, time, sys
import subprocess

time.sleep(1)

forked_pid = os.fork()

if forked_pid == 0:
  print("I am child!")
  subprocess.Popen(['ping','-c','10','localhost'])
  print("Child Quit")
else:
  print("I am parent!")
  time.sleep(2)
  print("Parent Quit")

sys.exit()
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы