Справочная информация:
У меня есть C# программа, которую я запускаю под Mono на Linux (в частности, Raspbian). Я работаю над Python скриптом, который запускает эту программу, контролирует ее и грациозно убивает. Я использую subprocess.Popen
для запуска программы C# в режиме моно. Когда я запускаю Python в обычном режиме, я могу отправить SIGINT
процессу и вижу, как он получает его и хорошо очищается перед выходом.
Проблема : Я хочу иметь возможность запускать сценарий как службу SystemD, поэтому я создал простой файл службы SystemD. Теперь C# больше не грациозно завершается, а завершается немедленно, почти как SIGKILL
, а не SIGINT
.
Вот мой текущий простой тестовый код для решения этой проблемы:
import os
import signal
import time
import subprocess
call = ['mono', '/home/user/test.exe'] # (not the actual name of the program, changed for this post)
print('starting')
process = subprocess.Popen(call)
time.sleep(20)
print('sending term')
process.send_signal(signal.SIGINT)
print('term sent')
А вот мой служебный файл SystemD (изменил мое действительное имя пользователя на 'user'):
[Unit]
Description=Test
After=multi-user.target
[Service]
User=user
Group=user
WorkingDirectory=/home/user/testcode
Type=simple
ExecStart=/home/user/testcode/.venv/bin/python /home/user/testcode/test.py
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=testcode
[Install]
WantedBy=multi-user.target
Я пытался смотреть HTOP, чтобы увидеть, происходит ли что-то странное с что такое PID и GID для процессов Mono, но все выглядит более-менее одинаково между прямым запуском и запущенным сценарием SystemD Python.
К сожалению, программа Mono для меня представляет собой черный ящик поэтому у меня есть минимальное понимание того, что в нем происходит. У меня есть доступ к исходному коду, но я не имею опыта работы с C# и не знаю, с чего начать искать подсказки. Я могу сказать, завершается ли он корректно, так как он генерирует файл журнала, который я могу tail
, и выводит пару строк при правильном выходе. Эти строки не печатаются после принудительного завершения.
Что я пытался Я в основном экспериментировал с различными методами запуска программы с использованием Popen.
- Использование
shell=True
приводит к тому, что программа C# вообще не останавливается при нормальном запуске, но при запуске через SystemD она демонстрирует такое же неприличное поведение выхода, как и без shell=True
. - Я попробовал некоторые предложения из этой темы , а именно, используя
preexec_fn=os.setsid
и os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
из первого ответа с shell=True
и без него, но безуспешно. Как при обычном запуске, так и при запуске SystemD возникают незаметные выходы. - Я добавил
time.sleep(5)
в конец скрипта, чтобы дать C# время для выхода до выхода из скрипта. Без изменений. Я думал, что SystemD видит выход сценария Python и очищает все остальные процессы, которые он вызвал, прежде чем они получат шанс завершить работу корректно.