Программа Python все еще работает, но PID не может быть найден

1

Я запускаю отдельную дочернюю программу в фоновом режиме из моей родительской программы. После того как я выйду из родительской программы, я ожидаю, что 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) 
  • 0
    Вы уверены, что просто не пропустили это? Я попробовал ваш разрез, и для меня PYTHON_PROGRAM был runner.py . Когда я запускаю ps -fwp $(pgrep -f runner.py) я вижу процесс в порядке. Может ли быть так, что это не в нижней части списка или где-то легко заметить? Я должен также упомянуть, что это немного неортодоксальный способ раскошелиться на фоновый процесс. ;)
  • 0
    Прежде всего, спасибо большое! Это странно ... Я использовал PID, который возвращает модуль подпроцесса, и он возвращает 15789, а PID выполнения вашей команды - 15790. Вы знаете причину этого несоответствия? Также не могли бы вы уточнить, что является более ортодоксальным способом сделать это?
Показать ещё 1 комментарий
Теги:
subprocess
pid
nohup

1 ответ

1
Лучший ответ

Хорошо, это слишком велико для комментариев. 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.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню