Я запускаю отдельную дочернюю программу в фоновом режиме из моей родительской программы. После того как я выйду из родительской программы, я ожидаю, что OUTPUT_PATH
программа продолжит работу и OUTPUT_PATH
в OUTPUT_PATH
. И действительно, я вижу обновление файла журнала. Однако, поскольку я пытался найти PID из ps aux
я не могу его найти. может ли кто-нибудь объяснить это поведение? Что я делаю неправильно?
shellCommand = "nohup python PYTHON_PROGRAM ARGS >OUTPUT_PATH 2>&1 &"
subprocess.Popen(shellCommand, shell=True, preexec_fn=os.setpgrp)
Хорошо, это слишком велико для комментариев. ps -fwp $(pgrep -f PYTHON_PROGRAM)
, мы нашли этот процесс сейчас. :) Но его PID не совпадает с сообщением Popen.pid
. Это будет связано с экземпляром оболочки, который был вызван, поскольку вы использовали shell=True
. Первая fork
должна была вызвать оболочку, вторая - для вашего скрипта. Собственно, это описано в ссылке выше:
Обратите внимание: если вы установите аргумент оболочки True, это ID процесса порожденной оболочки.
Но см. ПРИМЕЧАНИЕ ниже.
Это подводит нас к "более ортодоксальному пути". Там, где мы входим, возможно, оспариваемая территория, разные люди, разные идеи. Не так много, возможно, первое, что было бы в соответствии с документацией, предлагающей не использовать shell=True
если вам действительно не нужно.
args требуется для всех вызовов и должна быть строкой или последовательностью аргументов программы. Предоставление последовательности аргументов обычно предпочтительнее, так как оно позволяет модулю заботиться о любом требуемом экранировании и цитировании аргументов (например, для разрешения пробелов в именах файлов). Если передать одну строку, либо оболочка должна быть Истиной (см. Ниже), либо строка должна просто называть исполняемую программу без указания каких-либо аргументов.
Существует также еще один раздел о (безопасности) последствиях несоблюдения рекомендации.
Таким образом, компиляция списка аргументов для запуска nohup
с вашим скриптом и обработки перенаправления вывода уже с помощью аргументов ключевого слова (stdout
, stderr
) Popen
показала бы хороший ход действий и также обеспечит вам согласованный PID.
Этот последний шаг может вызвать большинство противоречий: но вы можете фактически демонизировать процесс с помощью интерфейсов python для соответствующих системных вызовов. Хорошо документированный пример, казалось бы, растет в github (доходит до одного прыжка из ссылки в PEP, упомянутой ниже).
или есть библиотека, на которую ссылается PEP-3143 на эту тему.
ПРИМЕЧАНИЕ. Этот бит не всегда является истинным (вызов sh
да, но два PID нет). По крайней мере, в моей системе я наблюдал sh
к exec
программы, вызываемой через -c
(сам по себе) без разветвления. Из нескольких быстрых прогонов и следов это было по крайней мере, если бы я не возился с stdin / -out / - err (т.е. Без труб или переадресаций), не форсировал подоболочку (...)
или не перехватывал команды более ;
, (Последние два являются очевидными, прежние - также, как только вы понимаете, как реализуются перенаправления). Так что, по крайней мере, для моей оболочки я бы осмелился экстраполировать и сказать: "Кажется, это не вилка, если это не так. Или даже более упрощенная (и, следовательно, не совсем правильная) формулировка будет: простой материал не будет fork.
PYTHON_PROGRAM
былrunner.py
. Когда я запускаюps -fwp $(pgrep -f runner.py)
я вижу процесс в порядке. Может ли быть так, что это не в нижней части списка или где-то легко заметить? Я должен также упомянуть, что это немного неортодоксальный способ раскошелиться на фоновый процесс. ;)