#python #systemd
#python #systemd
Вопрос:
У меня есть скрипт python, который периодически сканирует папку для обработки с помощью ffmpeg. Я решил превратить это в службу systemd. Скрипт нормально работал в командной строке, но выдает ошибку BlockingIOError, когда я пытаюсь запустить его как службу. Пытаясь разобраться в проблеме, я свел сценарий к почти примеру hello world, и я все еще получаю те же результаты. Вот что у меня есть:
foobar.py
import subprocess
result = subprocess.run(['/usr/bin/ffmpeg', '-h'])
print(result)
foobar.service
[Unit]
Description=foobar
[Service]
Type=simple
TasksMax=1
User=root
Environment="PATH=/usr/bin:/root/24-7"
ExecStart=/usr/bin/python3.8 /root/24-7/foobar.py
Исключение
Aug 26 12:47:55 Ubuntu-1804-bionic-64-minimal systemd[1]: Started foobar.
Aug 26 12:48:15 Ubuntu-1804-bionic-64-minimal python3.8[4539]: Traceback (most recent call last):
Aug 26 12:48:15 Ubuntu-1804-bionic-64-minimal python3.8[4539]: File "/root/24-7/foobar.py", line 6, in <module>
Aug 26 12:48:15 Ubuntu-1804-bionic-64-minimal python3.8[4539]: result = subprocess.run(['/usr/bin/ffmpeg', '-h'])
Aug 26 12:48:15 Ubuntu-1804-bionic-64-minimal python3.8[4539]: File "/usr/lib/python3.8/subprocess.py", line 489, in run
Aug 26 12:48:15 Ubuntu-1804-bionic-64-minimal python3.8[4539]: with Popen(*popenargs, **kwargs) as process:
Aug 26 12:48:15 Ubuntu-1804-bionic-64-minimal python3.8[4539]: File "/usr/lib/python3.8/subprocess.py", line 854, in __init__
Aug 26 12:48:15 Ubuntu-1804-bionic-64-minimal python3.8[4539]: self._execute_child(args, executable, preexec_fn, close_fds,
Aug 26 12:48:15 Ubuntu-1804-bionic-64-minimal python3.8[4539]: File "/usr/lib/python3.8/subprocess.py", line 1637, in _execute_child
Aug 26 12:48:15 Ubuntu-1804-bionic-64-minimal python3.8[4539]: self.pid = _posixsubprocess.fork_exec(
Aug 26 12:48:15 Ubuntu-1804-bionic-64-minimal python3.8[4539]: BlockingIOError: [Errno 11] Resource temporarily unavailable
Aug 26 12:48:15 Ubuntu-1804-bionic-64-minimal systemd[1]: foobar.service: Main process exited, code=exited, status=1/FAILURE
Aug 26 12:48:15 Ubuntu-1804-bionic-64-minimal systemd[1]: foobar.service: Failed with result 'exit-code'.
Не уверен, что еще попробовать. Я Даже попытался отложить вызов с помощью sleep(), чтобы посмотреть, не откроет ли ожидание нескольких секунд то, что блокирует. У меня нет идей, что попробовать. У кого-нибудь есть идеи?
Комментарии:
1. «Я свел сценарий к почти примеру hello world» — спасибо . Так мало людей на самом деле делают это, что приятно видеть вопрос, который это делает. Я проголосовал за вопрос соответствующим образом.
Ответ №1:
Проблема в вас TasksMax=1
. Это предотвращает разветвление дочерних процессов, и эффект не является специфичным для subprocess.run
— что-либо, такое как subprocess.Popen
или os.system
или os.fork
, или даже приложения, не являющиеся Python, пытающиеся разветвляться, будут испытывать аналогичные проблемы.
Здесь os.fork
отображаются аналогичные симптомы при условии TasksMax=1
:
foobar.py
import os
pid = os.fork()
if pid == 0:
print("child")
os._exit(0)
else:
print(os.waitpid(pid, 0))
Aug 26 12:25:57 moon systemd[1]: Started foobar.
Aug 26 12:25:57 moon python3.8[9477]: Traceback (most recent call last):
Aug 26 12:25:57 moon python3.8[9477]: File "/root/24-7/foobar.py", line 3, in <module>
Aug 26 12:25:57 moon python3.8[9477]: pid = os.fork()
Aug 26 12:25:57 moon python3.8[9477]: BlockingIOError: [Errno 11] Resource temporarily unavailable
Aug 26 12:25:57 moon systemd[1]: foobar.service: Main process exited, code=exited, status=1/FAILURE
Aug 26 12:25:57 moon systemd[1]: foobar.service: Failed with result 'exit-code'.
Если вы удалите эту строку или увеличите лимит, тогда это сработает.
Даже простое увеличение его до 2 работает для меня с вашим простым ffmpeg -h
примером, хотя с реальными параметрами, которые вы хотите запустить, вы можете увеличить его немного больше, на всякий случай, если ffmpeg
потребуется создать собственные дочерние процессы.
Комментарии:
1. Вот и все! Спасибо! Симптом копирования и вставки моего original .service из примера и никогда не обращал внимания на настройку TasksMax.